Core features: - Microkernel architecture with Actor model - Session management with JSONL persistence - Tool system (5 built-in tools) - Skill system with SKILL.md parsing - Sandbox security execution - Ollama integration with gemma4:e4b - Prompt-based tool calling (compatible with native function calling) - REPL interface 11 packages, all tests passing
101 lines
2.0 KiB
Go
101 lines
2.0 KiB
Go
package plugin
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
// Registry is a thread-safe map that manages plugin registration.
|
|
type Registry struct {
|
|
mu sync.RWMutex
|
|
plugins map[string]Plugin
|
|
states map[string]PluginState
|
|
}
|
|
|
|
// NewRegistry creates a new empty plugin registry.
|
|
func NewRegistry() *Registry {
|
|
return &Registry{
|
|
plugins: make(map[string]Plugin),
|
|
states: make(map[string]PluginState),
|
|
}
|
|
}
|
|
|
|
// Register adds a plugin to the registry.
|
|
func (r *Registry) Register(p Plugin) error {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
name := p.Name()
|
|
if _, exists := r.plugins[name]; exists {
|
|
return fmt.Errorf("plugin %q is already registered", name)
|
|
}
|
|
|
|
r.plugins[name] = p
|
|
r.states[name] = StateRegistered
|
|
return nil
|
|
}
|
|
|
|
// Unregister removes a plugin from the registry.
|
|
func (r *Registry) Unregister(name string) error {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
if _, exists := r.plugins[name]; !exists {
|
|
return fmt.Errorf("plugin %q is not registered", name)
|
|
}
|
|
|
|
delete(r.plugins, name)
|
|
delete(r.states, name)
|
|
return nil
|
|
}
|
|
|
|
// Get retrieves a plugin by name.
|
|
func (r *Registry) Get(name string) (Plugin, bool) {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
p, ok := r.plugins[name]
|
|
return p, ok
|
|
}
|
|
|
|
// List returns all registered plugins.
|
|
func (r *Registry) List() []Plugin {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
plugins := make([]Plugin, 0, len(r.plugins))
|
|
for _, p := range r.plugins {
|
|
plugins = append(plugins, p)
|
|
}
|
|
return plugins
|
|
}
|
|
|
|
// State returns the lifecycle state of a registered plugin.
|
|
func (r *Registry) State(name string) PluginState {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
if state, ok := r.states[name]; ok {
|
|
return state
|
|
}
|
|
return StateUnknown
|
|
}
|
|
|
|
// SetState updates the lifecycle state of a registered plugin.
|
|
func (r *Registry) SetState(name string, state PluginState) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
if _, ok := r.plugins[name]; ok {
|
|
r.states[name] = state
|
|
}
|
|
}
|
|
|
|
// Count returns the number of registered plugins.
|
|
func (r *Registry) Count() int {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
return len(r.plugins)
|
|
}
|