mirror of
https://github.com/val1813/kwcode.git
synced 2026-09-03 06:34:30 +08:00
Architecture upgrade to improve task completion for any model size: - SearchSubagent: independent context window, parallel file reads, clean results only - UpstreamManifest: deterministic AST extraction of signatures/constants, zero LLM - PENCIL-style compression: subtask results compacted to structured artifacts - Verifier pre-check: cross-file contract consistency before running tests - Generator context slimmed: upstream_constraints + retry_hint injection Code quality: - orchestrator.py run() split into 5 private methods (410->253 lines) - Full type annotations (Optional[DebugSubagent], Callable types) - __all__ added to 7 core modules - pyproject.toml: license fixed, ruff + mypy configured - TUI: 30+ event icons, Server: /api/manifest endpoint - STATUS.md rewritten: concise, English, professional format 451/451 tests green, 27 new tests for SearchSubagent+Manifest. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
"""
|
||
EventBus: 统一事件总线(Event Sourcing 模式)。
|
||
append-only 日志支持 replay/调试,替代分散的 on_status 回调。
|
||
|
||
理论来源:
|
||
- Event Sourcing(Martin Fowler)
|
||
- CC 27 个 hook 事件(arXiv:2604.14228)
|
||
- Codified Context append-only 日志(arXiv:2602.20478)
|
||
"""
|
||
|
||
from collections import defaultdict
|
||
from typing import Callable
|
||
import time
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
__all__ = ["EventBus"]
|
||
|
||
|
||
class EventBus:
|
||
"""
|
||
统一事件总线。
|
||
- on(event, handler) 注册监听
|
||
- emit(event, payload) 发射事件
|
||
- replay() 返回完整事件日志
|
||
"""
|
||
|
||
def __init__(self):
|
||
self._handlers: dict[str, list[Callable]] = defaultdict(list)
|
||
self._wildcard: list[Callable] = []
|
||
self._log: list[dict] = []
|
||
|
||
def on(self, event: str, handler: Callable):
|
||
"""注册事件处理器。event="*" 监听所有事件。"""
|
||
if event == "*":
|
||
self._wildcard.append(handler)
|
||
else:
|
||
self._handlers[event].append(handler)
|
||
|
||
def off(self, event: str, handler: Callable):
|
||
"""移除事件处理器。"""
|
||
if event == "*":
|
||
try:
|
||
self._wildcard.remove(handler)
|
||
except ValueError:
|
||
pass
|
||
else:
|
||
try:
|
||
self._handlers[event].remove(handler)
|
||
except ValueError:
|
||
pass
|
||
|
||
def emit(self, event: str, payload: dict | None = None):
|
||
"""发射事件,通知所有监听器,同时记录到日志。"""
|
||
payload = payload or {}
|
||
entry = {"t": time.time(), "event": event, **payload}
|
||
self._log.append(entry)
|
||
for h in self._handlers.get(event, []) + self._wildcard:
|
||
try:
|
||
h(event, payload)
|
||
except Exception as e:
|
||
logger.debug("EventBus handler error [%s]: %s", event, e)
|
||
|
||
def replay(self) -> list[dict]:
|
||
"""返回完整事件日志副本。"""
|
||
return list(self._log)
|
||
|
||
def clear_log(self):
|
||
"""清空事件日志(不影响已注册的handler)。"""
|
||
self._log.clear()
|
||
|
||
def handler_count(self) -> int:
|
||
"""返回已注册handler总数。"""
|
||
total = len(self._wildcard)
|
||
for handlers in self._handlers.values():
|
||
total += len(handlers)
|
||
return total
|