feat(tasks): add skill-templated task graph execution
This commit is contained in:
@ -2,6 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any
|
||||
|
||||
@ -126,6 +128,37 @@ class EvidenceBuilder:
|
||||
)
|
||||
|
||||
|
||||
def evaluate_node_evidence(
|
||||
evidence: RunEvidence,
|
||||
required_evidence: list[str],
|
||||
output_text: str,
|
||||
) -> list[str]:
|
||||
"""Evaluate v1 coarse-grained node evidence requirements."""
|
||||
|
||||
gaps: list[str] = []
|
||||
successful_tools = [
|
||||
item
|
||||
for item in evidence.tool_results
|
||||
if item.event_payload.get("success") is True
|
||||
]
|
||||
for raw_requirement in required_evidence:
|
||||
requirement = str(raw_requirement).strip()
|
||||
if not requirement:
|
||||
continue
|
||||
if requirement == "tool_result":
|
||||
if not successful_tools:
|
||||
_append_unique(gaps, "missing required evidence: tool_result")
|
||||
elif requirement == "url":
|
||||
if not any(_tool_evidence_contains_url(item) for item in successful_tools):
|
||||
_append_unique(gaps, "missing required evidence: url")
|
||||
elif requirement == "output":
|
||||
if not output_text.strip():
|
||||
_append_unique(gaps, "missing required evidence: output")
|
||||
else:
|
||||
_append_unique(gaps, f"unsupported evidence requirement: {requirement}")
|
||||
return gaps
|
||||
|
||||
|
||||
def render_task_evidence(packet: TaskEvidencePacket) -> str:
|
||||
sections = [
|
||||
f"Task evidence packet: task_id={packet.task_id} attempt={packet.attempt_index}",
|
||||
@ -181,3 +214,20 @@ def _render_tool_evidence(item: ToolEvidence) -> str:
|
||||
|
||||
def _optional_str(value: Any) -> str | None:
|
||||
return str(value) if value is not None else None
|
||||
|
||||
|
||||
_URL_RE = re.compile(r"https?://[^\s<>'\"]+", re.IGNORECASE)
|
||||
|
||||
|
||||
def _tool_evidence_contains_url(item: ToolEvidence) -> bool:
|
||||
values = [
|
||||
item.url or "",
|
||||
item.content,
|
||||
json.dumps(item.event_payload, ensure_ascii=False, default=str),
|
||||
]
|
||||
return any(_URL_RE.search(value) is not None for value in values)
|
||||
|
||||
|
||||
def _append_unique(values: list[str], value: str) -> None:
|
||||
if value not in values:
|
||||
values.append(value)
|
||||
|
||||
Reference in New Issue
Block a user