feat(engine): 添加运行时上下文支持并重构工具迭代限制
添加 RuntimeContext 类用于捕获模型运行时的日期时间信息, 包括UTC时间、本地时间和时区信息,并在系统提示中显示这些信息。 同时增加最大上下文消息数和工具迭代次数的配置选项, 将验证服务从引擎加载器中移除,并更新相关的数据结构和接口。 BREAKING CHANGE: 移除了验证服务,相关字段被替换为证据状态和接受状态。 - 添加 RuntimeContext 类和相关渲染方法 - 增加 max_context_messages 和 max_tool_iterations 配置 - 移除 ValidationService 相关代码 - 更新消息记录中的验证状态字段 - 添加原始工具调用检测和回退处理
This commit is contained in:
@ -69,15 +69,24 @@ class SkillLearningService:
|
||||
existing_ids.add(candidate.candidate_id)
|
||||
return candidates
|
||||
|
||||
def build_learning_candidates_for_task(self, task_id: str, *, trigger_run_id: str) -> list[SkillLearningCandidate]:
|
||||
"""Build candidates scoped to a single validated and satisfied Task run."""
|
||||
def build_learning_candidates_for_task(
|
||||
self,
|
||||
task_id: str,
|
||||
*,
|
||||
final_accepted_run_id: str | None = None,
|
||||
trigger_run_id: str | None = None,
|
||||
) -> list[SkillLearningCandidate]:
|
||||
"""Build candidates from a user-accepted Task and all of its runs."""
|
||||
|
||||
final_accepted_run_id = final_accepted_run_id or trigger_run_id
|
||||
if not final_accepted_run_id:
|
||||
return []
|
||||
runs = [record for record in self.run_store.list_runs() if record.task_id == task_id]
|
||||
trigger_run = next((record for record in runs if record.run_id == trigger_run_id), None)
|
||||
if trigger_run is None or not self._is_confirmed_positive_run(trigger_run):
|
||||
final_run = next((record for record in runs if record.run_id == final_accepted_run_id), None)
|
||||
if final_run is None or not self._is_task_accepted_run(final_run):
|
||||
return []
|
||||
|
||||
source_runs = [record for record in runs if self._is_confirmed_positive_run(record)]
|
||||
source_runs = sorted(runs, key=lambda item: (item.started_at, item.run_id))
|
||||
if not source_runs:
|
||||
return []
|
||||
|
||||
@ -100,11 +109,16 @@ class SkillLearningService:
|
||||
source_session_ids=source_session_ids,
|
||||
related_skill_names=[],
|
||||
reason=f"Task {task_id} completed successfully without a published skill; consider extracting reusable guidance.",
|
||||
evidence={"task_id": task_id, "trigger_run_id": trigger_run_id, "theme": self._task_theme(trigger_run.task_text)},
|
||||
evidence={
|
||||
"task_id": task_id,
|
||||
"final_accepted_run_id": final_accepted_run_id,
|
||||
"source_run_ids": source_run_ids,
|
||||
"theme": self._task_theme(final_run.task_text),
|
||||
},
|
||||
status="open",
|
||||
priority=1,
|
||||
confidence=0.8,
|
||||
trigger_reason="validation_accepted_and_user_satisfied",
|
||||
trigger_reason="task_accepted",
|
||||
)
|
||||
)
|
||||
else:
|
||||
@ -137,13 +151,14 @@ class SkillLearningService:
|
||||
),
|
||||
evidence={
|
||||
"task_id": task_id,
|
||||
"trigger_run_id": trigger_run_id,
|
||||
"final_accepted_run_id": final_accepted_run_id,
|
||||
"source_run_ids": source_run_ids,
|
||||
"skill_version": receipt.skill_version,
|
||||
},
|
||||
status="open",
|
||||
priority=1,
|
||||
confidence=0.7,
|
||||
trigger_reason="validation_accepted_and_user_satisfied",
|
||||
trigger_reason="task_accepted",
|
||||
)
|
||||
)
|
||||
|
||||
@ -269,7 +284,7 @@ class SkillLearningService:
|
||||
groups.setdefault(key, []).append(record)
|
||||
candidates: list[SkillLearningCandidate] = []
|
||||
for theme, runs in groups.items():
|
||||
successful = [record for record in runs if self._is_confirmed_positive_run(record)]
|
||||
successful = [record for record in runs if self._is_task_accepted_run(record)]
|
||||
if len(successful) < 2:
|
||||
continue
|
||||
if any(record.activated_skills for record in successful):
|
||||
@ -290,7 +305,7 @@ class SkillLearningService:
|
||||
def _build_merge_candidates(self) -> list[SkillLearningCandidate]:
|
||||
pair_counts: dict[tuple[str, str], list[RunRecord]] = {}
|
||||
for record in self.run_store.list_runs():
|
||||
if not self._is_confirmed_positive_run(record):
|
||||
if not self._is_task_accepted_run(record):
|
||||
continue
|
||||
unique = sorted({receipt.skill_name for receipt in record.activated_skills})
|
||||
for pair in combinations(unique, 2):
|
||||
@ -351,14 +366,15 @@ class SkillLearningService:
|
||||
return effects
|
||||
|
||||
@staticmethod
|
||||
def _is_confirmed_positive_run(record: RunRecord) -> bool:
|
||||
validation = record.validation_result or {}
|
||||
def _is_task_accepted_run(record: RunRecord) -> bool:
|
||||
feedback = record.feedback or {}
|
||||
acceptance_type = feedback.get("acceptance_type")
|
||||
if acceptance_type is None and feedback.get("feedback_type") == "satisfied":
|
||||
acceptance_type = "accept"
|
||||
return (
|
||||
bool(record.success)
|
||||
and bool(record.task_id)
|
||||
and validation.get("accepted") is True
|
||||
and feedback.get("feedback_type") == "satisfied"
|
||||
and acceptance_type == "accept"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user