Files
ai-agent-book/chapter9/gaia-experience/AWorld/aworld/runners/handler/task.py
T
liqiang b119135836
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
2026-08-20 13:12:50 +00:00

139 lines
6.6 KiB
Python

# coding: utf-8
# Copyright (c) 2025 inclusionAI.
import abc
import time
from typing import AsyncGenerator, TYPE_CHECKING
from aworld.core.common import TaskItem
from aworld.core.tool.base import Tool, AsyncTool
from aworld.core.event.base import Message, Constants, TopicType
from aworld.core.task import TaskResponse
from aworld.logs.util import logger
from aworld.output import Output
from aworld.runners import HandlerFactory
from aworld.runners.handler.base import DefaultHandler
from aworld.runners.hook.hook_factory import HookFactory
from aworld.runners.hook.hooks import HookPoint
if TYPE_CHECKING:
from aworld.runners.event_runner import TaskEventRunner
class TaskHandler(DefaultHandler):
__metaclass__ = abc.ABCMeta
def __init__(self, runner: 'TaskEventRunner'):
super().__init__(runner)
self.runner = runner
self.retry_count = runner.task.max_retry_count
self.hooks = {}
if runner.task.hooks:
for k, vals in runner.task.hooks.items():
self.hooks[k] = []
for v in vals:
cls = HookFactory.get_class(v)
if cls:
self.hooks[k].append(cls)
@classmethod
def name(cls):
return "_task_handler"
@HandlerFactory.register(name=f'__{Constants.TASK}__')
class DefaultTaskHandler(TaskHandler):
def is_valid_message(self, message: Message):
if message.category != Constants.TASK:
return False
return True
async def _do_handle(self, message: Message) -> AsyncGenerator[Message, None]:
if not self.is_valid_message(message):
return
logger.debug(f"task handler receive message: {message}")
headers = {"context": message.context}
topic = message.topic
task_item: TaskItem = message.payload
if topic == TopicType.SUBSCRIBE_TOOL:
new_tools = message.payload.data
for name, tool in new_tools.items():
if isinstance(tool, Tool) or isinstance(tool, AsyncTool):
await self.runner.event_mng.register(Constants.TOOL, name, tool.step)
logger.info(f"dynamic register {name} tool.")
else:
logger.warning(f"Unknown tool instance: {tool}")
return
elif topic == TopicType.SUBSCRIBE_AGENT:
return
elif topic == TopicType.ERROR:
async for event in self.run_hooks(message, HookPoint.ERROR):
yield event
logger.warning(f"task {self.runner.task.id} stop, cause: {task_item.msg}")
self.runner._task_response = TaskResponse(msg=task_item.msg,
answer='',
context=message.context,
success=False,
id=self.runner.task.id,
time_cost=(time.time() - self.runner.start_time),
usage=self.runner.context.token_usage)
if not self.runner.task.is_sub_task:
logger.info(f"FINISHED|DefaultTaskHandler|outputs|{self.runner.task.id} {self.runner.task.is_sub_task}")
await self.runner.task.outputs.mark_completed()
await self.runner.stop()
elif topic == TopicType.FINISHED:
async for event in self.run_hooks(message, HookPoint.FINISHED):
yield event
self.runner._task_response = TaskResponse(answer=message.payload,
success=True,
context=message.context,
id=self.runner.task.id,
time_cost=(time.time() - self.runner.start_time),
usage=self.runner.context.token_usage)
logger.info(f"FINISHED|task|{self.runner.task.id} finished. {self.runner.task.is_sub_task}")
if not self.runner.task.is_sub_task:
logger.info(f"FINISHED|DefaultTaskHandler|outputs|{self.runner.task.id} {self.runner.task.is_sub_task}")
await self.runner.task.outputs.mark_completed()
await self.runner.stop()
elif topic == TopicType.START:
async for event in self.run_hooks(message, HookPoint.START):
yield event
logger.info(f"task start event: {message}, will send init message.")
if message.payload:
yield message
else:
yield self.runner.init_message
elif topic == TopicType.OUTPUT:
yield message
elif topic == TopicType.HUMAN_CONFIRM:
logger.warn("=============== Get human confirm, pause execution ===============")
if self.runner.task.outputs and message.payload:
await self.runner.task.outputs.add_output(Output(data=message.payload))
self.runner._task_response = TaskResponse(answer=message.payload,
success=True,
context=message.context,
id=self.runner.task.id,
time_cost=(time.time() - self.runner.start_time),
usage=self.runner.context.token_usage)
await self.runner.stop()
elif topic == TopicType.CANCEL:
# Avoid waiting to receive events and send a mock event for quick cancel
yield Message(session_id=self.runner.context.session_id, sender=self.name(), category='mock', headers={"context": message.context})
# mark task response as cancelled
self.runner._task_response = TaskResponse(answer='',
success=False,
context=message.context,
id=self.runner.task.id,
time_cost=(time.time() - self.runner.start_time),
usage=self.runner.context.token_usage,
msg=f'cancellation message received: {task_item.msg}',
status='cancelled')
await self.runner.stop()