28 lines
1.2 KiB
Python
28 lines
1.2 KiB
Python
"""WebEventSink:实现 §7 A 的 sink 协议,把 AgentLoop.emit 桥到 RunBroker。
|
||
|
||
绑 task_id(0004 简化:run_id 已合并入 task 当前状态)。`emit({type, ...})` 直接转
|
||
broker.emit(task_id, event)。sink 实例由 web 层在启 run 时创建,传进 AgentLoop;
|
||
loop 完全不知 web 存在(§5 Less Scaffolding)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
from uuid import UUID
|
||
|
||
|
||
class WebEventSink:
|
||
def __init__(self, broker, task_id: UUID) -> None:
|
||
# broker: LocalRunBroker | RedisRunBroker(鸭子类型同接口,web/broker.py)
|
||
self._broker = broker
|
||
self._task_id = task_id
|
||
|
||
def emit(self, event: dict[str, Any]) -> None:
|
||
# AgentLoop 的 done 早于 web worker 把 tasks.run_status 落回 idle。若把这个
|
||
# 早到终态直接发给浏览器,客户端收尾回读可能仍看到 running,继而重建一张
|
||
# 永不该存在的“思考中”卡。Web run 的唯一终态由 run_agent_bg finally 中的
|
||
# broker.close() 在 DB 状态写完后发送;CLI 等非 Web sink 不受影响。
|
||
if event.get("type") == "done":
|
||
return
|
||
self._broker.emit(self._task_id, event)
|