Module: Legion::Extensions::Apollo::Runners::Expertise

Includes:
Helpers::Lex
Included in:
Client
Defined in:
lib/legion/extensions/apollo/runners/expertise.rb

Instance Method Summary collapse

Instance Method Details

#agent_profile(agent_id:) ⇒ Object



16
17
18
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 16

def agent_profile(agent_id:, **)
  { action: :agent_profile, agent_id: agent_id }
end

#aggregateObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 20

def aggregate(**)
  unless defined?(Legion::Data::Model::ApolloEntry)
    log.warn('Apollo Expertise.aggregate skipped: apollo_data_not_available')
    return { success: false, error: 'apollo_data_not_available' }
  end

  entries = Legion::Data::Model::ApolloEntry
            .select(:source_agent, :tags, :confidence)
            .exclude(source_agent: nil)
            .all
  log.debug("Apollo Expertise.aggregate entries=#{entries.size}")

  agent_set = Set.new
  domain_set = Set.new

  expertise_groups(entries).each_value do |group|
    upsert_expertise_group(group)
    agent_set << group[:agent_id]
    domain_set << group[:domain]
  end

  { success: true, agents: agent_set.size, domains: domain_set.size }
    .tap { |result| log.info("Apollo Expertise.aggregate agents=#{result[:agents]} domains=#{result[:domains]}") }
rescue Sequel::Error => e
  handle_exception(e, level: :error, operation: 'apollo.expertise.aggregate')
  { success: false, error: e.message }
end

#domains_at_risk(min_agents: Helpers::Confidence.apollo_setting(:expertise, :min_agents_at_risk, default: 2)) ⇒ Object



12
13
14
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 12

def domains_at_risk(min_agents: Helpers::Confidence.apollo_setting(:expertise, :min_agents_at_risk, default: 2), **)
  { action: :domains_at_risk, min_agents: min_agents }
end

#expertise_groups(entries) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 48

def expertise_groups(entries)
  entries.each_with_object({}) do |entry, groups|
    agent = entry.source_agent
    domain = entry.tags.is_a?(Array) ? (entry.tags.first || 'general') : 'general'
    key = "#{agent}:#{domain}"
    groups[key] ||= { agent_id: agent, domain: domain, confidences: [] }
    groups[key][:confidences] << entry.confidence.to_f
  end
end

#expertise_proficiency(confidences) ⇒ Object



74
75
76
77
78
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 74

def expertise_proficiency(confidences)
  avg = confidences.sum / confidences.size
  cap = Helpers::Confidence.apollo_setting(:expertise, :proficiency_cap, default: 1.0)
  [avg * Math.log2(confidences.size + 1), cap].min
end

#get_expertise(domain:, min_proficiency: Helpers::Confidence.apollo_setting(:expertise, :initial_proficiency, default: 0.0)) ⇒ Object



8
9
10
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 8

def get_expertise(domain:, min_proficiency: Helpers::Confidence.apollo_setting(:expertise, :initial_proficiency, default: 0.0), **)
  { action: :expertise_query, domain: domain, min_proficiency: min_proficiency }
end

#upsert_expertise_group(group) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/legion/extensions/apollo/runners/expertise.rb', line 58

def upsert_expertise_group(group)
  count = group[:confidences].size
  proficiency = expertise_proficiency(group[:confidences])
  existing = Legion::Data::Model::ApolloExpertise
             .where(agent_id: group[:agent_id], domain: group[:domain]).first

  if existing
    existing.update(proficiency: proficiency, entry_count: count, last_active_at: Time.now)
  else
    Legion::Data::Model::ApolloExpertise.create(
      agent_id: group[:agent_id], domain: group[:domain],
      proficiency: proficiency, entry_count: count, last_active_at: Time.now
    )
  end
end