115 lines
2.5 KiB
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]
|
|
}
|