Class: SuperInstance::Equipment::SwarmCoordinator::AsymmetricKnowledge

Inherits:
Object
  • Object
show all
Defined in:
lib/equipment/swarm_coordinator/asymmetric_knowledge.rb

Overview

AsymmetricKnowledge manages the distribution of knowledge across agents ensuring each agent only has access to what they need.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ AsymmetricKnowledge

Creates a new AsymmetricKnowledge manager

Parameters:

  • config (Hash) (defaults to: {})

    Configuration options



116
117
118
119
120
121
122
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 116

def initialize(config = {})
  @config = KnowledgeConfig.new(**config)
  @partitions = {}
  @access_policies = {}
  @global_knowledge = {}
  @knowledge_graph = KnowledgeGraph.new
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



112
113
114
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 112

def config
  @config
end

Instance Method Details

#add_global_knowledge(entry) ⇒ String

Add knowledge to global store

Parameters:

  • entry (Hash)

    Knowledge entry

Returns:

  • (String)

    Entry ID



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 168

def add_global_knowledge(entry)
  id = generate_id

  full_entry = KnowledgeEntry.new(
    id: id,
    key: entry[:key],
    value: entry[:value],
    level: entry[:level] || Types::KnowledgeLevel::PARTIAL,
    source: entry[:source],
    confidence: entry[:confidence] || 1.0,
    created_at: DateTime.now,
    expires_at: entry[:expires_at],
    tags: entry[:tags] || []
  )

  @global_knowledge[entry[:key]] = full_entry
  @knowledge_graph.add_node(entry[:key], full_entry)

  id
end

#can_access(agent_id, key) ⇒ Boolean

Check if an agent can access specific knowledge

Parameters:

  • agent_id (String)

    Agent identifier

  • key (String)

    Knowledge key

Returns:

  • (Boolean)

    True if access allowed



265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 265

def can_access(agent_id, key)
  partition = @partitions[agent_id]
  return false unless partition

  case @config.isolation_level
  when Types::IsolationLevel::STRICT
    check_strict_access(agent_id, key)
  when Types::IsolationLevel::MODERATE
    check_moderate_access(agent_id, key)
  when Types::IsolationLevel::RELAXED
    true
  end
end

#create_partition(agent_id, role) ⇒ KnowledgePartition

Create a knowledge partition for an agent

Parameters:

  • agent_id (String)

    Agent identifier

  • role (Symbol)

    Agent role

Returns:

Raises:



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 128

def create_partition(agent_id, role)
  raise Error, "Partition already exists for agent #{agent_id}" if @partitions.key?(agent_id)

  access_level = determine_access_level(role)

  partition = KnowledgePartition.new(
    partition_id: "partition-#{agent_id}",
    agent_id: agent_id,
    entries: {},
    access_level: access_level,
    created_at: DateTime.now,
    updated_at: DateTime.now,
    provenance: []
  )

  @partitions[agent_id] = partition
  partition
end

#distribute_knowledge(agent_id, key, value, source) ⇒ Boolean

Distribute knowledge to an agent

Parameters:

  • agent_id (String)

    Target agent ID

  • key (String)

    Knowledge key

  • value (Object)

    Knowledge value

  • source (String)

    Source identifier

Returns:

  • (Boolean)

    True if distributed successfully



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 195

def distribute_knowledge(agent_id, key, value, source)
  partition = @partitions[agent_id]
  return false unless partition

  return false unless can_access(agent_id, key)

  entry_id = generate_id
  entry = KnowledgeEntry.new(
    id: entry_id,
    key: key,
    value: value,
    level: partition.access_level,
    source: source,
    confidence: 1.0,
    created_at: DateTime.now,
    expires_at: nil,
    tags: []
  )

  partition.entries[key] = entry
  partition = partition.with(updated_at: DateTime.now)

  if @config.enable_provenance
    provenance = KnowledgeProvenance.new(
      origin_id: generate_origin_id,
      source_agent: source,
      transformation: nil,
      timestamp: DateTime.now
    )
    partition = partition.with(provenance: partition.provenance + [provenance])
  end

  @partitions[agent_id] = partition
  true
end

#get_distribution_scoreFloat

Get knowledge distribution score

Returns:

  • (Float)

    Distribution score (0-1)



320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 320

def get_distribution_score
  return 1.0 if @partitions.empty?

  total_knowledge = @global_knowledge.size
  return 1.0 if total_knowledge.zero?

  distributed_count = @partitions.values.sum { |p| p.entries.size }

  average_per_agent = distributed_count.to_f / @partitions.size
  ideal_distribution = total_knowledge.to_f / @partitions.size

  [1.0, average_per_agent / ideal_distribution].min
end

#get_knowledge_summary(agent_id) ⇒ KnowledgeSummary

Get knowledge summary for an agent

Parameters:

  • agent_id (String)

    Agent identifier

Returns:



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 337

def get_knowledge_summary(agent_id)
  partition = @partitions[agent_id]

  unless partition
    return KnowledgeSummary.new(
      agent_id: agent_id,
      entry_count: 0,
      categories: {},
      last_updated: DateTime.now,
      provenance_depth: 0
    )
  end

  categories = Hash.new(0)
  partition.entries.values.each do |entry|
    entry.tags.each { |tag| categories[tag] += 1 }
  end

  KnowledgeSummary.new(
    agent_id: agent_id,
    entry_count: partition.entries.size,
    categories: categories,
    last_updated: partition.updated_at,
    provenance_depth: partition.provenance.length
  )
end

#get_partition(agent_id) ⇒ KnowledgePartition?

Get a knowledge partition

Parameters:

  • agent_id (String)

    Agent identifier

Returns:



161
162
163
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 161

def get_partition(agent_id)
  @partitions[agent_id]
end

#prune_expired_knowledgeInteger

Prune expired knowledge entries

Returns:

  • (Integer)

    Number of entries pruned



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 366

def prune_expired_knowledge
  pruned_count = 0
  now = DateTime.now

  @partitions.each do |agent_id, partition|
    expired_keys = partition.entries.select do |_, entry|
      entry.expires_at && entry.expires_at < now
    end.keys

    expired_keys.each do |key|
      partition.entries.delete(key)
      pruned_count += 1
    end
  end

  pruned_count
end

#remove_partition(agent_id) ⇒ Boolean

Remove a knowledge partition

Parameters:

  • agent_id (String)

    Agent identifier

Returns:

  • (Boolean)

    True if removed successfully



150
151
152
153
154
155
156
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 150

def remove_partition(agent_id)
  return false unless @partitions.key?(agent_id)

  @partitions.delete(agent_id)
  @access_policies.delete(agent_id)
  true
end

#request_knowledge(requesting_agent_id, target_agent_id, key) ⇒ KnowledgeEntry?

Request knowledge from another agent

Parameters:

  • requesting_agent_id (String)

    Agent requesting knowledge

  • target_agent_id (String)

    Agent to request from

  • key (String)

    Knowledge key to request

Returns:



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 236

def request_knowledge(requesting_agent_id, target_agent_id, key)
  policies = @access_policies[requesting_agent_id] || []
  has_policy = policies.any? do |p|
    p.source_agent_id == target_agent_id &&
      matches_pattern(key, p.allowed_keys) &&
      !matches_pattern(key, p.denied_keys)
  end

  if !has_policy && @config.isolation_level == Types::IsolationLevel::STRICT
    return nil
  end

  target_partition = @partitions[target_agent_id]
  return nil unless target_partition

  entry = target_partition.entries[key]
  return nil unless entry

  return nil unless can_share(entry, requesting_agent_id)

  distribute_knowledge(requesting_agent_id, key, entry.value, target_agent_id)

  entry
end

#revoke_access_policy(target_agent_id, policy_id) ⇒ Boolean

Revoke access policy

Parameters:

  • target_agent_id (String)

    Target agent ID

  • policy_id (String)

    Policy ID to revoke

Returns:

  • (Boolean)

    True if revoked successfully



307
308
309
310
311
312
313
314
315
316
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 307

def revoke_access_policy(target_agent_id, policy_id)
  policies = @access_policies[target_agent_id]
  return false unless policies

  index = policies.index { |p| p.policy_id == policy_id }
  return false unless index

  policies.delete_at(index)
  true
end

#set_access_policy(policy) ⇒ String

Set access policy between agents

Parameters:

  • policy (Hash)

    Access policy to set

Returns:

  • (String)

    Policy ID



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 282

def set_access_policy(policy)
  policy_id = generate_id

  full_policy = AccessPolicy.new(
    policy_id: policy_id,
    source_agent_id: policy[:source_agent_id],
    target_agent_id: policy[:target_agent_id],
    allowed_keys: policy[:allowed_keys] || [],
    denied_keys: policy[:denied_keys] || [],
    granted_level: policy[:granted_level] || Types::KnowledgeLevel::PARTIAL,
    expires_at: policy[:expires_at],
    conditions: policy[:conditions] || []
  )

  existing_policies = @access_policies[policy[:target_agent_id]] || []
  existing_policies << full_policy
  @access_policies[policy[:target_agent_id]] = existing_policies

  policy_id
end

#transfer_knowledge(source_agent_id, target_agent_id, keys = nil) ⇒ Integer

Transfer knowledge between agents

Parameters:

  • source_agent_id (String)

    Source agent

  • target_agent_id (String)

    Target agent

  • keys (Array<String>, nil) (defaults to: nil)

    Keys to transfer (all if not specified)

Returns:

  • (Integer)

    Number of entries transferred



389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/equipment/swarm_coordinator/asymmetric_knowledge.rb', line 389

def transfer_knowledge(source_agent_id, target_agent_id, keys = nil)
  source_partition = @partitions[source_agent_id]
  target_partition = @partitions[target_agent_id]

  return 0 unless source_partition && target_partition

  keys_to_transfer = keys || source_partition.entries.keys
  transferred_count = 0

  keys_to_transfer.each do |key|
    if can_access(target_agent_id, key)
      entry = source_partition.entries[key]
      if entry
        distribute_knowledge(target_agent_id, key, entry.value, source_agent_id)
        transferred_count += 1
      end
    end
  end

  transferred_count
end