package api import ( "time" "crypto-miner-server/internal/epidemiology" ) func (h *WSHub) epidemiologyTracker() *epidemiology.Tracker { if h == nil { return nil } return h.epidemiology } // SetEpidemiologyReporter wires AI + Seer broadcast callbacks for mining interrupts. func (h *WSHub) SetEpidemiologyReporter(r epidemiology.Reporter) { if h == nil || h.epidemiology == nil { return } h.epidemiology.SetReporter(r) } func (h *WSHub) observeEpidemiologyFromStats(agentID string, in epidemiology.StatsInput) { tr := h.epidemiologyTracker() if tr == nil { return } tr.ObserveStats(agentID, in) } func (h *WSHub) attachEpidemiologyFix(resp map[string]interface{}, agentID string) { tr := h.epidemiologyTracker() if tr == nil { return } fix, ok := tr.ConsumeFix(agentID) if !ok { return } resp["epidemiology_fix"] = fix } func (h *WSHub) broadcastSeerEvent(ev epidemiology.SeerEvent) { h.broadcastDashboard(Message{Type: "seer_event", Payload: mustMarshal(ev)}) } func (h *WSHub) recordMiningInterruptAI(agentID, reasoning string) { if h.aiHandler == nil { return } entry := AIActivityEntry{ AgentID: agentID, LastAction: "mining_interrupt", LastReasoning: truncateStr(reasoning, 240), LastReportAt: time.Now(), } h.aiHandler.recordActivity(entry) } // WireDefaultEpidemiologyReporter connects mining-interrupt telemetry to AI + Seer streams. func (h *WSHub) WireDefaultEpidemiologyReporter() { if h == nil { return } h.SetEpidemiologyReporter(epidemiology.Reporter{ OnAI: func(agentID, action, reasoning string) { h.recordMiningInterruptAI(agentID, reasoning) }, OnSeer: func(ev epidemiology.SeerEvent) { h.broadcastSeerEvent(ev) }, }) }