Module: Legate::GlobalDefinitionRegistry
- Defined in:
- lib/legate/global_definition_registry.rb
Overview
In-memory registry for AgentDefinition instances. Serves as both the runtime definition registry (used by agents) and as a drop-in replacement for the Redis-backed DefinitionStore used by the Web UI.
Internal structure:
@registry = { name_symbol => { definition: AgentDefinition, metadata: {} } }
The ‘register`, `find`, `all`, and `clear!` methods maintain backward compatibility with the original API. The new methods (`get_definition`, `save_definition`, `update_definition`, `delete_definition`, `list_definitions`, `check_connection`, `definition_exists?`) provide the DefinitionStore interface the Web UI routes expect.
Constant Summary collapse
- DEFINITION_FIELDS =
Checks if a key corresponds to a field on AgentDefinition.
%i[ description instruction tool_names model_name temperature fallback_mode mcp_servers webhook_enabled webhook_secret agent_type planning_strategy sub_agent_names output_key sequential_sub_agent_names parallel_sub_agent_names loop_sub_agent_names delegation_targets loop_max_iterations loop_condition_state_key loop_condition_expected_value auth_credential_names auth_url_mappings auth_scheme_assignments auth_credential_assignments ].freeze
- WEB_TO_DEFINITION_MAP =
Web UI uses different field names; map them to definition ivars.
{ tools: :tool_names, model: :model_name, mcp_servers_json: :mcp_servers }.freeze
Class Method Summary collapse
-
.all ⇒ Hash{Symbol => Legate::AgentDefinition}
Returns the current registry hash mapping names to AgentDefinition objects.
-
.check_connection ⇒ Boolean
Always returns true for the in-memory store (no external connection to check).
-
.clear! ⇒ Object
Clears the registry (primarily for testing).
-
.definition_exists?(name) ⇒ Boolean
Checks if an agent definition with the given name exists.
-
.delete_definition(name) ⇒ Boolean
Deletes an agent definition from the registry.
-
.find(name) ⇒ Legate::AgentDefinition?
Finds an AgentDefinition instance by name.
-
.get_definition(name) ⇒ Hash?
Retrieves a single agent definition as a hash with Web UI field names.
-
.list_definitions ⇒ Array<Hash>
Returns an array of hashes, each in the same format as get_definition output.
-
.register(definition) ⇒ Boolean
Registers an AgentDefinition instance.
-
.save_definition(*args, **kwargs) ⇒ Boolean
Saves a new agent definition.
-
.update_definition(name, updates) ⇒ Boolean
Updates specific fields of an existing agent definition’s metadata.
Class Method Details
.all ⇒ Hash{Symbol => Legate::AgentDefinition}
Returns the current registry hash mapping names to AgentDefinition objects.
71 72 73 74 75 |
# File 'lib/legate/global_definition_registry.rb', line 71 def self.all @mutex.synchronize do @registry.transform_values { |entry| entry[:definition] }.dup end end |
.check_connection ⇒ Boolean
Always returns true for the in-memory store (no external connection to check).
198 199 200 |
# File 'lib/legate/global_definition_registry.rb', line 198 def self.check_connection true end |
.clear! ⇒ Object
Clears the registry (primarily for testing).
64 65 66 67 |
# File 'lib/legate/global_definition_registry.rb', line 64 def self.clear! @mutex.synchronize { @registry = {} } Legate.logger.debug('GlobalDefinitionRegistry: Cleared.') end |
.definition_exists?(name) ⇒ Boolean
Checks if an agent definition with the given name exists.
205 206 207 208 209 210 |
# File 'lib/legate/global_definition_registry.rb', line 205 def self.definition_exists?(name) sym_name = normalize_name(name) return false unless sym_name @mutex.synchronize { @registry.key?(sym_name) } end |
.delete_definition(name) ⇒ Boolean
Deletes an agent definition from the registry.
178 179 180 181 182 183 184 185 |
# File 'lib/legate/global_definition_registry.rb', line 178 def self.delete_definition(name) sym_name = normalize_name(name) return true unless sym_name # Nothing to delete @mutex.synchronize { @registry.delete(sym_name) } Legate.logger.info("GlobalDefinitionRegistry: Deleted definition for :#{sym_name}") true end |
.find(name) ⇒ Legate::AgentDefinition?
Finds an AgentDefinition instance by name.
54 55 56 57 58 59 60 61 |
# File 'lib/legate/global_definition_registry.rb', line 54 def self.find(name) unless name.is_a?(Symbol) Legate.logger.warn("GlobalDefinitionRegistry: Find called with non-symbol key: #{name.inspect}") return nil end entry = @mutex.synchronize { @registry[name] } entry&.[](:definition) end |
.get_definition(name) ⇒ Hash?
Retrieves a single agent definition as a hash with Web UI field names.
Field name mapping from AgentDefinition#to_h:
:tool_names -> :tools (Array of Symbols)
:model_name -> :model (Symbol or nil)
:mcp_servers -> :mcp_servers_json (JSON String)
Metadata fields (e.g. :persistent_status, :last_run_at) are merged in.
92 93 94 95 96 97 98 99 100 |
# File 'lib/legate/global_definition_registry.rb', line 92 def self.get_definition(name) sym_name = normalize_name(name) return nil unless sym_name entry = @mutex.synchronize { @registry[sym_name] } return nil unless entry build_web_hash(entry) end |
.list_definitions ⇒ Array<Hash>
Returns an array of hashes, each in the same format as get_definition output.
189 190 191 192 193 194 |
# File 'lib/legate/global_definition_registry.rb', line 189 def self.list_definitions entries = @mutex.synchronize { @registry.dup } entries.map { |_name, entry| build_web_hash(entry) } .compact .sort_by { |d| d[:name].to_s } end |
.register(definition) ⇒ Boolean
Registers an AgentDefinition instance.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/legate/global_definition_registry.rb', line 30 def self.register(definition) unless definition.is_a?(Legate::AgentDefinition) && definition.name.is_a?(Symbol) Legate.logger.error("GlobalDefinitionRegistry: Invalid object passed to register: #{definition.inspect}") return false end name = definition.name @mutex.synchronize do if @registry.key?(name) Legate.logger.warn("GlobalDefinitionRegistry: Overwriting existing definition for agent :#{name}") # Preserve existing metadata when re-registering = @registry[name][:metadata] || {} @registry[name] = { definition: definition, metadata: } else @registry[name] = { definition: definition, metadata: {} } end end Legate.logger.debug("GlobalDefinitionRegistry: Registered definition for :#{name}") true end |
.save_definition(*args, **kwargs) ⇒ Boolean
Saves a new agent definition. Supports two call signatures:
-
Keyword splat (from the create form):
save_definition(name:, description:, tools:, model:, ...) -
Two positional args (from the duplicate route):
save_definition(new_name, definition_hash)
111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/legate/global_definition_registry.rb', line 111 def self.save_definition(*args, **kwargs) if args.length == 2 # Positional form: save_definition(new_name, definition_hash) new_name = args[0] definition_hash = args[1] _save_from_hash(new_name, definition_hash) elsif args.empty? && !kwargs.empty? # Keyword form: save_definition(name:, description:, tools:, model:, ...) _save_from_keywords(**kwargs) else raise ArgumentError, 'save_definition expects either (name, hash) or keyword arguments' end end |
.update_definition(name, updates) ⇒ Boolean
Updates specific fields of an existing agent definition’s metadata. This is used for things like persistent_status, last_run_at, and also for updating definition fields via the Web UI edit forms.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/legate/global_definition_registry.rb', line 132 def self.update_definition(name, updates) sym_name = normalize_name(name) return false unless sym_name @mutex.synchronize do entry = @registry[sym_name] return false unless entry definition = entry[:definition] # Snapshot for atomic rollback: a web edit that left the definition in a # state the constructor would reject (e.g. cleared instruction) used to # persist silently. We apply the batch, then validate! once and restore # the prior state on failure. (update_definition_field reassigns ivars # rather than mutating in place, so a shallow snapshot is a faithful # rollback.) ivar_snapshot = definition&.instance_variables&.to_h { |iv| [iv, definition.instance_variable_get(iv)] } = entry[:metadata].dup updates.each do |key, value| key_sym = key.to_sym # Check if this is a field that should update the AgentDefinition itself update_definition_field(definition, key_sym, value) if definition_field?(key_sym) && definition # Always store in metadata as well (for fields like persistent_status, # last_run_at, and as a cache for definition field overrides) entry[:metadata][key_sym] = value end if definition begin definition.validate! rescue StandardError => e ivar_snapshot.each { |iv, val| definition.instance_variable_set(iv, val) } entry[:metadata].replace() Legate.logger.error("GlobalDefinitionRegistry: Rejected update for :#{sym_name} (would leave the definition invalid): #{e.}") return false end end end Legate.logger.debug("GlobalDefinitionRegistry: Updated definition for :#{sym_name} with keys: #{updates.keys.join(', ')}") true end |