feat(beaver): 完成Task Team功能v1实现,重构后端架构支持统一内核

新增内部Task系统,包括验证、反馈门控机制,实现自动质量验证
(通过率>=0.75)和用户反馈闭环(satisfied/revise/abandon)。

实现Agent Team v1协调器,支持sequence/parallel/dag执行策略,
sub-agent复用主AgentLoop,每个run使用独立memory snapshot。

建立Skill学习pipeline,包含draft/审核/发布/回滚完整生命周期,
通过Task验证通过且用户满意才生成学习候选。

重构目录结构,移除third_party依赖,建立统一engine内核,
所有agent共享运行时基础组件。

更新ContextBuilder清理provider消息字段,增强SkillContext版本管理,
集成TaskExecutionPlanner和TaskSkillResolver实现技能解析机制。
This commit is contained in:
2026-05-08 17:14:14 +08:00
parent 5ba5c7e4c1
commit 8a12c30141
93 changed files with 16724 additions and 1247 deletions

View File

@ -45,6 +45,10 @@ class SlowService:
return AgentService.build_outbound_message(inbound, result)
class InvalidService:
is_running = True
def test_gateway_routes_memory_channel_roundtrip() -> None:
async def run() -> None:
bus = MessageBus()
@ -124,6 +128,23 @@ def test_gateway_rejects_channel_manager_and_channels_together() -> None:
asyncio.run(run())
def test_gateway_fails_fast_for_service_without_handle_inbound_message() -> None:
async def run() -> None:
try:
await run_gateway(
service=InvalidService(),
manage_service_lifecycle=False,
bus=MessageBus(),
stop_event=asyncio.Event(),
)
except TypeError as exc:
assert "handle_inbound_message" in str(exc)
else:
raise AssertionError("expected TypeError")
asyncio.run(run())
def test_agent_service_maps_inbound_error_to_structured_outbound() -> None:
async def run() -> None:
service = AgentService()
@ -144,6 +165,24 @@ def test_agent_service_maps_inbound_error_to_structured_outbound() -> None:
asyncio.run(run())
def test_agent_service_maps_stopped_runtime_to_stopped_outbound() -> None:
async def run() -> None:
service = AgentService()
async def stopped_submit_direct(message: str, **kwargs: Any) -> FakeResult:
raise RuntimeError("AgentLoop.submit_direct() is not accepting new tasks after stop()")
service.submit_direct = stopped_submit_direct # type: ignore[method-assign]
outbound = await service.handle_inbound_message(
InboundMessage(channel="memory", content="hello", session_id="s1")
)
assert outbound.finish_reason == "stopped"
assert "not accepting new tasks" in outbound.metadata["error"]
asyncio.run(run())
def test_channel_manager_start_cancellation_rolls_back_started_channels() -> None:
class StartedChannel:
name = "started"