返回 DeepSeek-Reasonix
mcp_list_observer.go
根目录 / internal / agent / mcp_list_observer.go
1 package agent
2
3 import (
4 "encoding/json"
5 "fmt"
6
7 "reasonix/internal/event"
8 "reasonix/internal/i18n"
9 )
10
11 type mcpListObservation struct {
12 Server string `json:"server"`
13 Source string `json:"source"`
14 Trigger string `json:"trigger"`
15 DurationMs int64 `json:"duration_ms"`
16 ToolCount int `json:"tool_count"`
17 SchemaBytes int `json:"schema_bytes"`
18 NetworkCall bool `json:"network_call"`
19 }
20
21 type mcpListObserverBinder interface {
22 bindMCPListObserver(func(mcpListObservation))
23 }
24
25 type mcpListObserverActivator interface {
26 activateMCPListObserver() func()
27 }
28
29 func (a *Agent) bindCapabilityObservers() {
30 a.bindToolResultSessionCapability()
31 a.bindMCPListObserverCapability()
32 }
33
34 func (a *Agent) activateMCPListObserver() func() {
35 if a == nil || a.svc.tools == nil {
36 return func() {}
37 }
38 proxy, ok := a.svc.tools.Get("use_capability")
39 if !ok {
40 return func() {}
41 }
42 activator, ok := proxy.(mcpListObserverActivator)
43 if !ok {
44 return func() {}
45 }
46 return activator.activateMCPListObserver()
47 }
48
49 // capabilityProxyNoticeText renders the EmitProxyAudit line from the catalogue.
50 func capabilityProxyNoticeText(displayName, targetName string) string {
51 return fmt.Sprintf(i18n.M.CapabilityProxyFmt, displayName, targetName)
52 }
53
54 func (a *Agent) bindMCPListObserverCapability() {
55 if a == nil || a.svc.tools == nil {
56 return
57 }
58 proxy, ok := a.svc.tools.Get("use_capability")
59 if !ok {
60 return
61 }
62 binder, ok := proxy.(mcpListObserverBinder)
63 if !ok {
64 return
65 }
66 binder.bindMCPListObserver(func(observation mcpListObservation) {
67 detail, _ := json.Marshal(observation)
68 a.svc.sink.Emit(event.Event{
69 Kind: event.Notice, Level: event.LevelInfo,
70 Code: event.NoticeCodeMCPToolsList, Text: "MCP tools/list",
71 Detail: string(detail),
72 })
73 })
74 }
75
76 func (t *UseCapabilityTool) bindMCPListObserver(observer func(mcpListObservation)) {
77 if t == nil {
78 return
79 }
80 t.mcpListMu.Lock()
81 t.mcpListObserver = observer
82 t.mcpListMu.Unlock()
83 }
84
85 func (t *UseCapabilityTool) observeMCPList(observation mcpListObservation) {
86 t.mcpListMu.RLock()
87 observer := t.mcpListObserver
88 t.mcpListMu.RUnlock()
89 if observer != nil {
90 observer(observation)
91 }
92 }
93
94 func (t *UseCapabilityTool) activateMCPListObserver() func() {
95 if t == nil || t.runtime == nil {
96 return func() {}
97 }
98 return t.runtime.activateFrontend(t)
99 }
100
100 lines GO