ollie/cmd/toolsrv/registry.go

115 lines
2.5 KiB
Go

// registry.go - Session-scoped tool registry for toolsrv.
package main
import (
"fmt"
"sort"
"sync"
"ollie/toolsrv"
)
// Registry tracks loaded tools per session.
type Registry struct {
mu sync.RWMutex
sessions map[string]map[string]toolsrv.ToolInfo
revisions map[string]uint64
}
// NewRegistry creates a new tool registry.
func NewRegistry() (*Registry, error) {
r := &Registry{
sessions: make(map[string]map[string]toolsrv.ToolInfo),
revisions: make(map[string]uint64),
}
return r, nil
}
// discover scans the tools directory and returns all valid tool infos.
func (r *Registry) discover() map[string]toolsrv.ToolInfo {
infos := toolsrv.DiscoverTools()
tools := make(map[string]toolsrv.ToolInfo, len(infos))
for _, info := range infos {
tools[info.Name] = info
}
return tools
}
// Load loads a tool into a session's registry.
func (r *Registry) Load(sessionID, name string) error {
tools := r.discover()
tool, exists := tools[name]
if !exists {
return fmt.Errorf("tool not found: %s", name)
}
r.mu.Lock()
defer r.mu.Unlock()
if r.sessions[sessionID] == nil {
r.sessions[sessionID] = make(map[string]toolsrv.ToolInfo)
}
r.sessions[sessionID][name] = tool
r.revisions[sessionID]++
return nil
}
// Unload removes a tool from a session's registry.
func (r *Registry) Unload(sessionID, name string) error {
r.mu.Lock()
defer r.mu.Unlock()
sessionTools, ok := r.sessions[sessionID]
if !ok {
return nil
}
if _, exists := sessionTools[name]; !exists {
return nil
}
delete(sessionTools, name)
r.revisions[sessionID]++
return nil
}
// Loaded returns all tools loaded for a session.
func (r *Registry) Loaded(sessionID string) []toolsrv.ToolInfo {
r.mu.RLock()
defer r.mu.RUnlock()
sessionTools, ok := r.sessions[sessionID]
if !ok {
return nil
}
var loaded []toolsrv.ToolInfo
for _, info := range sessionTools {
loaded = append(loaded, info)
}
sort.Slice(loaded, func(i, j int) bool { return loaded[i].Name < loaded[j].Name })
return loaded
}
// Lookup returns a tool by name from a session's registry.
func (r *Registry) Lookup(sessionID, name string) (toolsrv.ToolInfo, bool) {
r.mu.RLock()
defer r.mu.RUnlock()
sessionTools, ok := r.sessions[sessionID]
if !ok {
return toolsrv.ToolInfo{}, false
}
tool, exists := sessionTools[name]
return tool, exists
}
// Revision returns the revision counter for a session's registry.
func (r *Registry) Revision(sessionID string) uint64 {
r.mu.RLock()
defer r.mu.RUnlock()
return r.revisions[sessionID]
}