feat(task): 添加任务修订功能和超时处理机制
添加了 `revise_task` 路由动作类型,允许用户修改、纠正或重新执行最新活动任务结果。 实现了工具失败指导原则,防止相同类别工具重复失败。 为任务规划器添加了超时处理机制,避免长时间等待。 BREAKING CHANGE: 任务路由逻辑已更新,新增 `revise_task` 动作类型。 fix(api): 修复任务详情API返回完整流程投影 修复了任务详情API端点,现在会包含过滤后的流程运行、事件和工件信息, 并确保时间戳字段正确序列化。 refactor(engine): 优化任务技能解析器摘要节点处理 改进了任务技能解析器对摘要节点的处理逻辑,对于仅依赖文本生成功能的摘要节 点不再分配具体技能,直接使用依赖项输出进行汇总。 test: 增加任务修订和超时处理测试用例 添加了测试用例验证任务修订输入记录反馈、超时回退到单模式以及 摘要节点技能解析等新功能。
This commit is contained in:
@ -1635,6 +1635,8 @@ def create_app(
|
||||
|
||||
@app.get("/api/tasks/{task_id}")
|
||||
async def get_task(task_id: str, request: Request) -> dict[str, Any]:
|
||||
from beaver.services.process_service import SessionProcessProjector
|
||||
|
||||
loaded = get_agent_service(request).create_loop().boot()
|
||||
task_service = loaded.task_service
|
||||
if task_service is None:
|
||||
@ -1642,10 +1644,18 @@ def create_app(
|
||||
task = task_service.get_task(task_id)
|
||||
if task is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
process_projection = SessionProcessProjector(
|
||||
loaded.session_manager,
|
||||
loaded.run_memory_store,
|
||||
).project(task.session_id)
|
||||
filtered_process = _filter_task_process_projection(process_projection, task_id)
|
||||
return {
|
||||
**task_service.to_api_dict(task),
|
||||
"events": [event.to_dict() for event in task_service.list_events(task_id)],
|
||||
"runs": _task_run_views(task, task_service.list_events(task_id), loaded.session_manager, loaded.run_memory_store), # type: ignore[arg-type]
|
||||
"process_runs": filtered_process["runs"],
|
||||
"process_events": filtered_process["events"],
|
||||
"process_artifacts": filtered_process["artifacts"],
|
||||
}
|
||||
|
||||
@app.delete("/api/tasks/{task_id}")
|
||||
@ -2153,6 +2163,33 @@ def _task_run_views(task: Any, events: list[Any], session_manager: Any, run_memo
|
||||
return views
|
||||
|
||||
|
||||
def _filter_task_process_projection(projection: dict[str, Any], task_id: str) -> dict[str, list[dict[str, Any]]]:
|
||||
def belongs_to_task(item: dict[str, Any]) -> bool:
|
||||
metadata = item.get("metadata")
|
||||
return isinstance(metadata, dict) and metadata.get("task_id") == task_id
|
||||
|
||||
def with_task_metadata(item: dict[str, Any]) -> dict[str, Any]:
|
||||
copied = dict(item)
|
||||
metadata = dict(copied.get("metadata") or {})
|
||||
metadata.setdefault("task_id", task_id)
|
||||
copied["metadata"] = metadata
|
||||
return copied
|
||||
|
||||
runs = [with_task_metadata(item) for item in projection.get("runs", []) if isinstance(item, dict) and belongs_to_task(item)]
|
||||
run_ids = {str(item.get("run_id")) for item in runs if item.get("run_id")}
|
||||
events = [
|
||||
with_task_metadata(item)
|
||||
for item in projection.get("events", [])
|
||||
if isinstance(item, dict) and (belongs_to_task(item) or str(item.get("run_id")) in run_ids)
|
||||
]
|
||||
artifacts = [
|
||||
with_task_metadata(item)
|
||||
for item in projection.get("artifacts", [])
|
||||
if isinstance(item, dict) and (belongs_to_task(item) or str(item.get("run_id")) in run_ids)
|
||||
]
|
||||
return {"runs": runs, "events": events, "artifacts": artifacts}
|
||||
|
||||
|
||||
def _agent_labels_for_task_events(events: list[Any]) -> dict[str, str]:
|
||||
labels: dict[str, str] = {}
|
||||
for event in events:
|
||||
|
||||
Reference in New Issue
Block a user