import time import logging from typing import Any from .event_bus import EventBus from .memory import MemoryEngine from .policy import PolicyEngine, PolicyContext from .observability import ObservabilityBrain from .healing import SelfHealingEngine logger = logging.getLogger("qkernel.core") EVENT_TYPES = { "USER_MESSAGE", "POLICY_DECISION", "MEMORY_READ", "MEMORY_WRITE", "TRACE_EVENT", "SERVICE_CALL", "RESPONSE_READY", "NODE_FAILURE", "HEALING_EVENT", } class BaseService: name: str = "base" async def process(self, event: dict) -> dict: raise NotImplementedError class QKernel: def __init__( self, memory: MemoryEngine | None = None, policy: PolicyEngine | None = None, obs: ObservabilityBrain | None = None, event_bus: EventBus | None = None, healer: SelfHealingEngine | None = None, ): self.memory = memory or MemoryEngine() self.policy = policy or PolicyEngine() self.obs = obs or ObservabilityBrain() self.bus = event_bus or EventBus() self.healer = healer or SelfHealingEngine() self._services: dict[str, BaseService] = {} def register_service(self, name: str, service: BaseService) -> None: service.name = name self._services[name] = service logger.info("Service registered: %s", name) def _route(self, event: dict) -> str: msg_type = event.get("type", "chat") if msg_type == "voice": return "voice" if msg_type == "network": return "network" return "brain" async def handle(self, event: dict) -> dict: start = time.time() trace_id = self.obs.start_trace(event) await self.bus.publish("USER_MESSAGE", event) policy_start = time.time() policy_ctx: PolicyContext = self.policy.evaluate(event) self.obs.record_latency("policy_latency", time.time() - policy_start) await self.bus.publish("POLICY_DECISION", { "trace_id": trace_id, "allowed": policy_ctx.allowed, "route_override": policy_ctx.route_override, "priority_boost": policy_ctx.priority_boost, }) if not policy_ctx.allowed: self.obs.add_step(trace_id, "blocked_by_policy", { "reason": "policy_denied", }) self.obs.end_trace(trace_id, success=False) await self._check_healing({ "latency": (time.time() - start) * 1000, "error_rate": self.obs.get_metrics().get("error_rate", 0), }) return {"error": "blocked_by_policy", "trace_id": trace_id} service_name = policy_ctx.route_override or self._route(event) service = self._services.get(service_name) if service is None: self.obs.add_step(trace_id, "service_not_found", { "service": service_name, }) self.obs.end_trace(trace_id, success=False) return {"error": f"service_not_found: {service_name}", "trace_id": trace_id} memory_start = time.time() context = self.memory.read( event.get("user_id", "anonymous"), event.get("session_id", "default"), ) self.obs.record_latency("memory_latency", time.time() - memory_start) self.obs.add_step(trace_id, "memory_loaded", {"context_size": len(context)}) await self.bus.publish("MEMORY_READ", { "trace_id": trace_id, "user_id": event.get("user_id"), "session_id": event.get("session_id"), "context_size": len(context), }) enriched = { **event, "context": context, "trace_id": trace_id, } await self.bus.publish("SERVICE_CALL", { "trace_id": trace_id, "service": service_name, }) service_start = time.time() result = await service.process(enriched) self.obs.record_latency("service_latency", time.time() - service_start) self.obs.add_step(trace_id, "service_completed", { "service": service_name, "latency": time.time() - service_start, }) response_text = result.get("response", "") memory_write_start = time.time() self.memory.write( event.get("user_id", "anonymous"), event.get("session_id", "default"), "assistant", response_text, ) self.obs.record_latency("memory_latency", time.time() - memory_write_start) await self.bus.publish("MEMORY_WRITE", { "trace_id": trace_id, "response_length": len(response_text), }) self.obs.end_trace(trace_id, success=True) await self.bus.publish("RESPONSE_READY", { "trace_id": trace_id, "response_length": len(response_text), }) total_time = time.time() - start await self._check_healing({ "latency": total_time * 1000, "error_rate": self.obs.get_metrics().get("error_rate", 0), }) return { **result, "trace_id": trace_id, "processing_time_ms": round(total_time * 1000, 2), } async def _check_healing(self, metrics: dict) -> None: if self.healer.detect(metrics): await self.bus.publish("HEALING_EVENT", metrics) def get_stats(self) -> dict: return { "memory": self.memory.get_stats(), "metrics": self.obs.get_metrics(), "services": list(self._services.keys()), "healing_history": len(self.healer.get_history()), }