66 "fmt"
77 "os"
88 "strings"
9+ "sync"
910
1011 "github.com/GrayCodeAI/eyrie/client"
1112 "github.com/GrayCodeAI/hawk/internal/intelligence/memory"
@@ -145,6 +146,7 @@ func canonicalForReadOnly(name string) string {
145146
146147// Registry holds all registered tools.
147148type Registry struct {
149+ mu sync.RWMutex
148150 tools map [string ]Tool
149151 primary []Tool
150152}
@@ -171,19 +173,25 @@ func NewRegistry(tools ...Tool) *Registry {
171173
172174// Get returns a tool by name.
173175func (r * Registry ) Get (name string ) (Tool , bool ) {
176+ r .mu .RLock ()
177+ defer r .mu .RUnlock ()
174178 t , ok := r .tools [name ]
175179 return t , ok
176180}
177181
178182// PrimaryTools returns the model-visible tools registered in this registry.
179183func (r * Registry ) PrimaryTools () []Tool {
184+ r .mu .RLock ()
185+ defer r .mu .RUnlock ()
180186 out := make ([]Tool , len (r .primary ))
181187 copy (out , r .primary )
182188 return out
183189}
184190
185191// Filter returns a new Registry containing only tools whose names are in the allowlist.
186192func (r * Registry ) Filter (allow []string ) * Registry {
193+ r .mu .RLock ()
194+ defer r .mu .RUnlock ()
187195 set := make (map [string ]bool , len (allow ))
188196 for _ , name := range allow {
189197 set [name ] = true
@@ -199,6 +207,8 @@ func (r *Registry) Filter(allow []string) *Registry {
199207
200208// EyrieTools converts all tools to eyrie tool definitions for the API.
201209func (r * Registry ) EyrieTools () []client.EyrieTool {
210+ r .mu .RLock ()
211+ defer r .mu .RUnlock ()
202212 out := make ([]client.EyrieTool , 0 , len (r .primary ))
203213 for _ , t := range r .primary {
204214 out = append (out , client.EyrieTool {
@@ -212,6 +222,8 @@ func (r *Registry) EyrieTools() []client.EyrieTool {
212222
213223// Execute runs a tool by name with the given JSON input.
214224func (r * Registry ) Execute (ctx context.Context , name string , input json.RawMessage ) (string , error ) {
225+ r .mu .RLock ()
226+ defer r .mu .RUnlock ()
215227 t , ok := r .tools [name ]
216228 if ! ok {
217229 return "" , fmt .Errorf ("unknown tool: %s" , name )
@@ -222,6 +234,8 @@ func (r *Registry) Execute(ctx context.Context, name string, input json.RawMessa
222234// Register adds a tool to the registry after creation.
223235// Returns error if a tool with the same name already exists (unless it's an alias).
224236func (r * Registry ) Register (t Tool ) error {
237+ r .mu .Lock ()
238+ defer r .mu .Unlock ()
225239 if _ , exists := r .tools [t .Name ()]; exists {
226240 return fmt .Errorf ("tool %q already registered" , t .Name ())
227241 }
0 commit comments