返回 DeepSeek-Reasonix
sink.go
根目录 / internal / notify / sink.go
1 package notify
2
3 import (
4 "reasonix/internal/config"
5 "reasonix/internal/event"
6 )
7
8 // Message is the user-visible payload sent to the platform notifier.
9 type Message struct {
10 Title string
11 Body string
12 }
13
14 // Sender delivers a notification without taking ownership of event routing.
15 type Sender interface {
16 Send(Message) error
17 }
18
19 // Sink forwards every event to inner and mirrors configured attention events to sender.
20 type Sink struct {
21 event.AuditForwarder
22 inner event.Sink
23 sender Sender
24 cfg config.NotificationsConfig
25 }
26
27 // NewSink wraps an existing event sink with best-effort notification delivery.
28 func NewSink(inner event.Sink, sender Sender, cfg config.NotificationsConfig) *Sink {
29 return &Sink{AuditForwarder: event.AuditForwarder{Inner: inner}, inner: inner, sender: sender, cfg: cfg}
30 }
31
32 // Emit preserves the underlying event stream before attempting notification side effects.
33 func (s *Sink) Emit(e event.Event) {
34 if s.inner != nil {
35 s.inner.Emit(e)
36 }
37 SendEvent(s.sender, s.cfg, e)
38 }
39
40 // SendEvent applies the same notification rules for paths that do not emit through Sink.
41 func SendEvent(sender Sender, cfg config.NotificationsConfig, e event.Event) {
42 if !cfg.Enabled || sender == nil {
43 return
44 }
45 if msg, ok := message(cfg, e); ok {
46 _ = sender.Send(msg)
47 }
48 }
49
50 func message(cfg config.NotificationsConfig, e event.Event) (Message, bool) {
51 switch e.Kind {
52 case event.TurnDone:
53 if cfg.TurnDone {
54 if e.Err != nil {
55 return Message{Title: "Reasonix", Body: "Turn failed"}, true
56 }
57 return Message{Title: "Reasonix", Body: "Turn finished"}, true
58 }
59 case event.ApprovalRequest:
60 if cfg.ApprovalRequest {
61 return Message{Title: "Reasonix", Body: "Approval needed"}, true
62 }
63 case event.AskRequest:
64 if cfg.AskRequest {
65 return Message{Title: "Reasonix", Body: "Question needs your answer"}, true
66 }
67 }
68 return Message{}, false
69 }
70
70 lines GO