Module: A2A::Plugin
- Defined in:
- lib/a2a/plugin.rb
Defined Under Namespace
Modules: Events Classes: AuthPlugin, Base, MiddlewarePlugin, TransportPlugin
Class Attribute Summary collapse
-
.hooks ⇒ Hash<Symbol, Array>
readonly
Registered hooks.
-
.registry ⇒ Hash<Symbol, Hash>
readonly
Registry of all plugins.
Class Method Summary collapse
-
.add_hook(event, callable = nil, priority: 50, &block) ⇒ Object
Register a hook.
-
.clear! ⇒ Object
Clear all plugins (for testing).
-
.execute_hooks(event, *args) ⇒ Array
Execute hooks for an event.
-
.initialize! ⇒ Object
Initialize plugin system.
-
.list ⇒ Hash
List all registered plugins.
-
.load(name, **config) ⇒ Object
Load a plugin.
-
.loaded?(name) ⇒ Boolean
Check if a plugin is loaded.
-
.loaded_plugins(type: nil) ⇒ Array<Object>
Get loaded plugins by type.
-
.register(name, plugin_class, **options) ⇒ Object
Register a plugin.
-
.unload(name) ⇒ Object
Unload a plugin.
Class Attribute Details
.hooks ⇒ Hash<Symbol, Array> (readonly)
Registered hooks
33 34 35 |
# File 'lib/a2a/plugin.rb', line 33 def hooks @hooks end |
.registry ⇒ Hash<Symbol, Hash> (readonly)
Registry of all plugins
29 30 31 |
# File 'lib/a2a/plugin.rb', line 29 def registry @registry end |
Class Method Details
.add_hook(event, callable = nil, priority: 50, &block) ⇒ Object
Register a hook
130 131 132 133 134 135 136 137 138 |
# File 'lib/a2a/plugin.rb', line 130 def add_hook(event, callable = nil, priority: 50, &block) initialize! unless @hooks handler = callable || block raise ArgumentError, "Must provide callable or block" unless handler @hooks[event] << { callable: handler, priority: priority } @hooks[event].sort_by! { |hook| hook[:priority] } end |
.clear! ⇒ Object
Clear all plugins (for testing)
181 182 183 184 185 186 |
# File 'lib/a2a/plugin.rb', line 181 def clear! @loaded_plugins&.each { |name| unload(name) } @registry&.clear @hooks&.clear initialize! end |
.execute_hooks(event, *args) ⇒ Array
Execute hooks for an event
144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/a2a/plugin.rb', line 144 def execute_hooks(event, *args) initialize! unless @hooks results = [] @hooks[event].each do |hook| result = hook[:callable].call(*args) results << result rescue StandardError => e A2A.config.logger&.error("Hook execution failed for #{event}: #{e.message}") raise A2A::Errors::PluginError, "Hook execution failed: #{e.message}" end results end |
.initialize! ⇒ Object
Initialize plugin system
36 37 38 39 40 |
# File 'lib/a2a/plugin.rb', line 36 def initialize! @registry = {} @hooks = Hash.new { |h, k| h[k] = [] } @loaded_plugins = Set.new end |
.list ⇒ Hash
List all registered plugins
168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/a2a/plugin.rb', line 168 def list initialize! unless @registry @registry.transform_values do |info| { type: info[:type], loaded: info[:loaded], options: info[:options] } end end |
.load(name, **config) ⇒ Object
Load a plugin
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/a2a/plugin.rb', line 67 def load(name, **config) initialize! unless @registry plugin_info = @registry[name] raise A2A::Errors::PluginError, "Plugin not found: #{name}" unless plugin_info return plugin_info[:instance] if plugin_info[:loaded] begin instance = plugin_info[:class].new(**config) plugin_info[:instance] = instance plugin_info[:loaded] = true @loaded_plugins << name # Register plugin hooks instance.register_hooks(self) if instance.respond_to?(:register_hooks) A2A.config.logger&.info("Loaded plugin: #{name}") instance rescue StandardError => e raise A2A::Errors::PluginError, "Failed to load plugin #{name}: #{e.message}" end end |
.loaded?(name) ⇒ Boolean
Check if a plugin is loaded
161 162 163 164 |
# File 'lib/a2a/plugin.rb', line 161 def loaded?(name) initialize! unless @registry @loaded_plugins.include?(name) end |
.loaded_plugins(type: nil) ⇒ Array<Object>
Get loaded plugins by type
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/a2a/plugin.rb', line 114 def loaded_plugins(type: nil) initialize! unless @registry plugins = @loaded_plugins.filter_map { |name| @registry[name][:instance] } if type plugins.select { |plugin| plugin.class.plugin_type == type } else plugins end end |
.register(name, plugin_class, **options) ⇒ Object
Register a plugin
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/a2a/plugin.rb', line 46 def register(name, plugin_class, **) initialize! unless @registry unless plugin_class.respond_to?(:plugin_type) raise A2A::Errors::PluginError, "Plugin class must include A2A::Plugin::Base" end @registry[name] = { class: plugin_class, type: plugin_class.plugin_type, options: , loaded: false } A2A.config.logger&.info("Registered plugin: #{name} (#{plugin_class.plugin_type})") end |
.unload(name) ⇒ Object
Unload a plugin
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/a2a/plugin.rb', line 93 def unload(name) initialize! unless @registry plugin_info = @registry[name] return unless plugin_info && plugin_info[:loaded] instance = plugin_info[:instance] # Call cleanup if available instance.cleanup if instance.respond_to?(:cleanup) plugin_info[:loaded] = false plugin_info[:instance] = nil @loaded_plugins.delete(name) A2A.config.logger&.info("Unloaded plugin: #{name}") end |