|
@@ -15,6 +15,7 @@ from typing import Any, Literal
|
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
|
|
|
|
|
|
from cyber_agent.core.artifacts import ArtifactRef
|
|
from cyber_agent.core.artifacts import ArtifactRef
|
|
|
|
|
+from cyber_agent.core.agent_mode import policy_from_context
|
|
|
from cyber_agent.core.task_contract import TaskContractRef
|
|
from cyber_agent.core.task_contract import TaskContractRef
|
|
|
from cyber_agent.core.validation import RetryFrom
|
|
from cyber_agent.core.validation import RetryFrom
|
|
|
from cyber_agent.application.candidate import CandidateRef, CandidateReviewAction
|
|
from cyber_agent.application.candidate import CandidateRef, CandidateReviewAction
|
|
@@ -708,10 +709,23 @@ def ensure_task_protocol(context: dict[str, Any]) -> dict[str, Any]:
|
|
|
Runner、Sub-Agent 和报告/审核工具在读写任务状态前统一调用此入口。
|
|
Runner、Sub-Agent 和报告/审核工具在读写任务状态前统一调用此入口。
|
|
|
"""
|
|
"""
|
|
|
state = context.get("task_protocol")
|
|
state = context.get("task_protocol")
|
|
|
|
|
+ policy = policy_from_context(context)
|
|
|
|
|
+ strict = policy.requires_task_progress
|
|
|
if not isinstance(state, dict):
|
|
if not isinstance(state, dict):
|
|
|
|
|
+ if strict:
|
|
|
|
|
+ raise ValueError(
|
|
|
|
|
+ "Recursive revision 3 task_protocol is missing or invalid"
|
|
|
|
|
+ )
|
|
|
state = new_task_protocol()
|
|
state = new_task_protocol()
|
|
|
context["task_protocol"] = state
|
|
context["task_protocol"] = state
|
|
|
defaults = new_task_protocol()
|
|
defaults = new_task_protocol()
|
|
|
|
|
+ if strict:
|
|
|
|
|
+ missing = sorted(set(defaults).difference(state))
|
|
|
|
|
+ if missing:
|
|
|
|
|
+ raise ValueError(
|
|
|
|
|
+ "Recursive revision 3 task_protocol is missing required fields: "
|
|
|
|
|
+ + ", ".join(missing)
|
|
|
|
|
+ )
|
|
|
for key, value in defaults.items():
|
|
for key, value in defaults.items():
|
|
|
state.setdefault(key, deepcopy(value))
|
|
state.setdefault(key, deepcopy(value))
|
|
|
if state.get("schema_version") != TASK_PROTOCOL_SCHEMA_VERSION:
|
|
if state.get("schema_version") != TASK_PROTOCOL_SCHEMA_VERSION:
|