active_genie 0.26.0 → 0.26.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +13 -9
- data/VERSION +1 -1
- data/lib/active_genie/battle/generalist.rb +8 -8
- data/lib/active_genie/clients/providers/anthropic_client.rb +2 -2
- data/lib/active_genie/clients/providers/base_client.rb +2 -2
- data/lib/active_genie/clients/providers/deepseek_client.rb +2 -2
- data/lib/active_genie/clients/providers/google_client.rb +3 -10
- data/lib/active_genie/clients/providers/openai_client.rb +2 -2
- data/lib/active_genie/config/README.md +235 -0
- data/lib/active_genie/config/log_config.rb +12 -15
- data/lib/active_genie/config/providers/anthropic_config.rb +2 -2
- data/lib/active_genie/config/providers/deepseek_config.rb +2 -2
- data/lib/active_genie/config/providers/google_config.rb +2 -2
- data/lib/active_genie/config/providers/openai_config.rb +2 -2
- data/lib/active_genie/config/providers/provider_base.rb +4 -4
- data/lib/active_genie/configuration.rb +16 -4
- data/lib/active_genie/data_extractor/generalist.rb +1 -1
- data/lib/active_genie/logger.rb +40 -22
- data/lib/active_genie/ranking/elo_round.rb +38 -38
- data/lib/active_genie/ranking/free_for_all.rb +29 -28
- data/lib/active_genie/ranking/player.rb +6 -18
- data/lib/active_genie/ranking/players_collection.rb +6 -2
- data/lib/active_genie/ranking/ranking.rb +32 -25
- data/lib/active_genie/ranking/ranking_scoring.rb +12 -17
- data/lib/active_genie/scoring/generalist.rb +8 -8
- data/lib/tasks/templates/active_genie.rb +1 -1
- metadata +3 -3
- data/lib/active_genie/ranking/concerns/loggable.rb +0 -29
data/lib/active_genie/logger.rb
CHANGED
@@ -4,47 +4,65 @@ require 'json'
|
|
4
4
|
require 'fileutils'
|
5
5
|
|
6
6
|
module ActiveGenie
|
7
|
-
|
8
|
-
|
7
|
+
class Logger
|
8
|
+
def initialize(log_config: nil)
|
9
|
+
@log_config = log_config || ActiveGenie.configuration.log
|
10
|
+
end
|
9
11
|
|
10
12
|
def call(data)
|
11
|
-
log =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
13
|
+
log = data.merge(@log_config.additional_context)
|
14
|
+
.merge(
|
15
|
+
timestamp: Time.now,
|
16
|
+
process_id: Process.pid
|
17
|
+
)
|
17
18
|
|
18
19
|
persist!(log)
|
19
|
-
|
20
|
+
output_call(log)
|
21
|
+
call_observers(log)
|
20
22
|
|
21
23
|
log
|
22
24
|
end
|
23
25
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
def merge(log_config = nil)
|
27
|
+
new(log_config:)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def call_observers(log)
|
33
|
+
Array(@log_config.observers).each do |observer|
|
34
|
+
next unless observer[:scope].all? { |key, value| log[key.to_sym] == value }
|
35
|
+
|
36
|
+
observer[:observer]&.call(log)
|
37
|
+
rescue StandardError => e
|
38
|
+
call(code: :observer_error, **observer, error: e.message)
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
|
-
|
42
|
+
def output_call(log)
|
43
|
+
if @log_config.output
|
44
|
+
@log_config.output&.call(log)
|
45
|
+
else
|
46
|
+
$stdout.puts log
|
47
|
+
end
|
48
|
+
rescue StandardError => e
|
49
|
+
call(code: :output_error, error: e.message)
|
50
|
+
end
|
37
51
|
|
38
52
|
def persist!(log)
|
39
|
-
file_path = log
|
53
|
+
file_path = log_to_file_path(log)
|
40
54
|
folder_path = File.dirname(file_path)
|
41
55
|
|
42
56
|
FileUtils.mkdir_p(folder_path)
|
43
57
|
File.write(file_path, "#{JSON.generate(log)}\n", mode: 'a')
|
44
58
|
end
|
45
59
|
|
46
|
-
def
|
47
|
-
|
60
|
+
def log_to_file_path(log)
|
61
|
+
if log.key?(:fine_tune) && log[:fine_tune]
|
62
|
+
@log_config.fine_tune_file_path
|
63
|
+
else
|
64
|
+
@log_config.file_path
|
65
|
+
end
|
48
66
|
end
|
49
67
|
end
|
50
68
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../battle/generalist'
|
4
|
-
|
5
3
|
module ActiveGenie
|
6
4
|
module Ranking
|
7
5
|
class EloRound
|
@@ -9,27 +7,26 @@ module ActiveGenie
|
|
9
7
|
new(...).call
|
10
8
|
end
|
11
9
|
|
12
|
-
def initialize(players, criteria, config:
|
10
|
+
def initialize(players, criteria, config: nil)
|
13
11
|
@players = players
|
14
12
|
@relegation_tier = players.calc_relegation_tier
|
15
13
|
@defender_tier = players.calc_defender_tier
|
16
14
|
@criteria = criteria
|
17
|
-
@config = config
|
15
|
+
@config = ActiveGenie.configuration.merge(config)
|
18
16
|
@tmp_defenders = []
|
19
17
|
@total_tokens = 0
|
20
|
-
@previous_elo = {}
|
18
|
+
@previous_elo = @players.to_h { |player| [player.id, player.elo] }
|
21
19
|
@previous_highest_elo = @defender_tier.max_by(&:elo).elo
|
22
20
|
end
|
23
21
|
|
24
22
|
def call
|
25
|
-
@
|
23
|
+
@config.log.add_observer(observers: ->(log) { log_observer(log) })
|
24
|
+
@config.log.additional_context = { elo_round_id: }
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
update_players_elo(winner, loser)
|
32
|
-
end
|
26
|
+
matches.each do |player_a, player_b|
|
27
|
+
# TODO: battle can take a while, can be parallelized
|
28
|
+
winner, loser = battle(player_a, player_b)
|
29
|
+
update_players_elo(winner, loser)
|
33
30
|
end
|
34
31
|
|
35
32
|
build_report
|
@@ -41,9 +38,16 @@ module ActiveGenie
|
|
41
38
|
private
|
42
39
|
|
43
40
|
def matches
|
41
|
+
match_keys = {}
|
42
|
+
|
44
43
|
@relegation_tier.each_with_object([]) do |attack_player, matches|
|
45
44
|
BATTLE_PER_PLAYER.times do
|
46
|
-
|
45
|
+
defense_player = next_defense_player
|
46
|
+
|
47
|
+
next if match_keys["#{attack_player.id}_#{defense_player.id}"]
|
48
|
+
|
49
|
+
match_keys["#{attack_player.id}_#{defense_player.id}"] = true
|
50
|
+
matches << [attack_player, defense_player]
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -55,22 +59,20 @@ module ActiveGenie
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def battle(player_a, player_b)
|
58
|
-
ActiveGenie::
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
[winner, loser]
|
73
|
-
end
|
62
|
+
result = ActiveGenie::Battle.call(
|
63
|
+
player_a.content,
|
64
|
+
player_b.content,
|
65
|
+
@criteria,
|
66
|
+
config: @config.merge(additional_context: { player_a_id: player_a.id, player_b_id: player_b.id })
|
67
|
+
)
|
68
|
+
|
69
|
+
winner, loser = case result['winner']
|
70
|
+
when 'player_a' then [player_a, player_b]
|
71
|
+
when 'player_b' then [player_b, player_a]
|
72
|
+
when 'draw' then [nil, nil]
|
73
|
+
end
|
74
|
+
|
75
|
+
[winner, loser]
|
74
76
|
end
|
75
77
|
|
76
78
|
def update_players_elo(winner, loser)
|
@@ -87,16 +89,14 @@ module ActiveGenie
|
|
87
89
|
player_rating + (K * (score - expected_score)).round
|
88
90
|
end
|
89
91
|
|
90
|
-
def log_context
|
91
|
-
{ elo_round_id: }
|
92
|
-
end
|
93
|
-
|
94
92
|
def elo_round_id
|
95
|
-
|
96
|
-
|
93
|
+
@elo_round_id ||= begin
|
94
|
+
relegation_tier_ids = @relegation_tier.map(&:id).join(',')
|
95
|
+
defender_tier_ids = @defender_tier.map(&:id).join(',')
|
97
96
|
|
98
|
-
|
99
|
-
|
97
|
+
ranking_unique_key = [relegation_tier_ids, defender_tier_ids, @criteria, @config.to_json].join('-')
|
98
|
+
Digest::MD5.hexdigest(ranking_unique_key)
|
99
|
+
end
|
100
100
|
end
|
101
101
|
|
102
102
|
def build_report
|
@@ -111,7 +111,7 @@ module ActiveGenie
|
|
111
111
|
players_elo_diff:
|
112
112
|
}
|
113
113
|
|
114
|
-
|
114
|
+
@config.logger.call({ elo_round_id:, code: :elo_round_report, **report })
|
115
115
|
|
116
116
|
report
|
117
117
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../battle/generalist'
|
4
|
-
|
5
3
|
module ActiveGenie
|
6
4
|
module Ranking
|
7
5
|
class FreeForAll
|
@@ -9,21 +7,22 @@ module ActiveGenie
|
|
9
7
|
new(...).call
|
10
8
|
end
|
11
9
|
|
12
|
-
def initialize(players, criteria, config:
|
10
|
+
def initialize(players, criteria, config: nil)
|
13
11
|
@players = players
|
14
12
|
@criteria = criteria
|
15
|
-
@config = config
|
13
|
+
@config = config || ActiveGenie.configuration
|
16
14
|
@start_time = Time.now
|
17
15
|
@total_tokens = 0
|
18
16
|
end
|
19
17
|
|
20
18
|
def call
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
@config.log.add_observer(observers: ->(log) { log_observer(log) })
|
20
|
+
@config.log.additional_context = { free_for_all_id: }
|
21
|
+
|
22
|
+
matches.each do |player_a, player_b|
|
23
|
+
winner, loser = battle(player_a, player_b)
|
24
24
|
|
25
|
-
|
26
|
-
end
|
25
|
+
update_players_score(winner, loser)
|
27
26
|
end
|
28
27
|
|
29
28
|
build_report
|
@@ -38,26 +37,30 @@ module ActiveGenie
|
|
38
37
|
end
|
39
38
|
|
40
39
|
def battle(player_a, player_b)
|
40
|
+
log_context = { player_a_id: player_a.id, player_b_id: player_b.id }
|
41
|
+
|
41
42
|
result = ActiveGenie::Battle.call(
|
42
43
|
player_a.content,
|
43
44
|
player_b.content,
|
44
45
|
@criteria,
|
45
|
-
config: @config
|
46
|
+
config: @config.merge(additional_context: log_context)
|
46
47
|
)
|
47
48
|
|
48
49
|
winner, loser = case result['winner']
|
49
|
-
when 'player_a' then [player_a, player_b
|
50
|
-
when 'player_b' then [player_b, player_a
|
51
|
-
when 'draw' then [nil, nil
|
50
|
+
when 'player_a' then [player_a, player_b]
|
51
|
+
when 'player_b' then [player_b, player_a]
|
52
|
+
when 'draw' then [nil, nil]
|
52
53
|
end
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
55
|
+
@config.logger.call(
|
56
|
+
{
|
57
|
+
**log_context,
|
58
|
+
code: :free_for_all_battle,
|
59
|
+
winner_id: winner&.id,
|
60
|
+
loser_id: loser&.id,
|
61
|
+
reasoning: result['reasoning']
|
62
|
+
}
|
63
|
+
)
|
61
64
|
|
62
65
|
[winner, loser]
|
63
66
|
end
|
@@ -74,14 +77,12 @@ module ActiveGenie
|
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
|
-
def log_context
|
78
|
-
{ free_for_all_id: }
|
79
|
-
end
|
80
|
-
|
81
80
|
def free_for_all_id
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
@free_for_all_id ||= begin
|
82
|
+
eligible_ids = @players.eligible.map(&:id).join(',')
|
83
|
+
ranking_unique_key = [eligible_ids, @criteria, @config.to_json].join('-')
|
84
|
+
Digest::MD5.hexdigest(ranking_unique_key)
|
85
|
+
end
|
85
86
|
end
|
86
87
|
|
87
88
|
def build_report
|
@@ -92,7 +93,7 @@ module ActiveGenie
|
|
92
93
|
total_tokens: @total_tokens
|
93
94
|
}
|
94
95
|
|
95
|
-
|
96
|
+
@config.logger.call({ code: :free_for_all_report, **report })
|
96
97
|
|
97
98
|
report
|
98
99
|
end
|
@@ -27,13 +27,7 @@ module ActiveGenie
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def elo
|
30
|
-
@elo =
|
31
|
-
@params[:elo]
|
32
|
-
elsif @score
|
33
|
-
generate_elo_by_score
|
34
|
-
else
|
35
|
-
BASE_ELO
|
36
|
-
end
|
30
|
+
@elo = @elo || @params[:elo] || generate_elo_by_score
|
37
31
|
end
|
38
32
|
|
39
33
|
def ffa_win_count
|
@@ -53,38 +47,30 @@ module ActiveGenie
|
|
53
47
|
end
|
54
48
|
|
55
49
|
def score=(value)
|
56
|
-
ActiveGenie::Logger.call({ code: :new_score, player_id: id, score: value }) if value != @score
|
57
50
|
@score = value
|
58
51
|
@elo = generate_elo_by_score
|
59
52
|
end
|
60
53
|
|
61
54
|
def elo=(value)
|
62
|
-
ActiveGenie::Logger.call({ code: :new_elo, player_id: id, elo: value }) if value != @elo
|
63
55
|
@elo = value || BASE_ELO
|
64
56
|
end
|
65
57
|
|
66
|
-
|
67
|
-
ActiveGenie::Logger.call({ code: :new_eliminated, player_id: id, eliminated: value }) if value != @eliminated
|
68
|
-
@eliminated = value
|
69
|
-
end
|
58
|
+
attr_writer :eliminated
|
70
59
|
|
71
60
|
def draw!
|
72
61
|
@ffa_draw_count += 1
|
73
|
-
ActiveGenie::Logger.call({ code: :new_ffa_score, player_id: id, result: 'draw', ffa_score: })
|
74
62
|
end
|
75
63
|
|
76
64
|
def win!
|
77
65
|
@ffa_win_count += 1
|
78
|
-
ActiveGenie::Logger.call({ code: :new_ffa_score, player_id: id, result: 'win', ffa_score: })
|
79
66
|
end
|
80
67
|
|
81
68
|
def lose!
|
82
69
|
@ffa_lose_count += 1
|
83
|
-
ActiveGenie::Logger.call({ code: :new_ffa_score, player_id: id, result: 'lose', ffa_score: })
|
84
70
|
end
|
85
71
|
|
86
72
|
def ffa_score
|
87
|
-
(
|
73
|
+
(ffa_win_count * 3) + ffa_draw_count
|
88
74
|
end
|
89
75
|
|
90
76
|
def sort_value
|
@@ -127,7 +113,9 @@ module ActiveGenie
|
|
127
113
|
private
|
128
114
|
|
129
115
|
def generate_elo_by_score
|
130
|
-
BASE_ELO
|
116
|
+
return BASE_ELO if @score.nil?
|
117
|
+
|
118
|
+
BASE_ELO + (@score - 50)
|
131
119
|
end
|
132
120
|
end
|
133
121
|
end
|
@@ -56,7 +56,7 @@ module ActiveGenie
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def to_json(*_args)
|
59
|
-
to_h.to_json
|
59
|
+
@players.map(&:to_h).to_json
|
60
60
|
end
|
61
61
|
|
62
62
|
def method_missing(...)
|
@@ -84,7 +84,11 @@ module ActiveGenie
|
|
84
84
|
def tier_size
|
85
85
|
size = (eligible_size / 3).ceil
|
86
86
|
|
87
|
-
|
87
|
+
if eligible_size < 10
|
88
|
+
(eligible_size / 2).ceil
|
89
|
+
else
|
90
|
+
size.clamp(10, eligible_size - 10)
|
91
|
+
end
|
88
92
|
end
|
89
93
|
end
|
90
94
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'concerns/loggable'
|
4
3
|
require_relative 'players_collection'
|
5
4
|
require_relative 'free_for_all'
|
6
5
|
require_relative 'elo_round'
|
@@ -32,8 +31,6 @@ require_relative 'ranking_scoring'
|
|
32
31
|
module ActiveGenie
|
33
32
|
module Ranking
|
34
33
|
class Ranking
|
35
|
-
include ActiveGenie::Concerns::Loggable
|
36
|
-
|
37
34
|
def self.call(...)
|
38
35
|
new(...).call
|
39
36
|
end
|
@@ -48,20 +45,19 @@ module ActiveGenie
|
|
48
45
|
|
49
46
|
def call
|
50
47
|
@players = create_players
|
48
|
+
@config.log.additional_context = { ranking_id: }
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
eliminate_obvious_bad_players!
|
55
|
-
|
56
|
-
while @players.elo_eligible?
|
57
|
-
elo_report = run_elo_round!
|
58
|
-
eliminate_relegation_players!
|
59
|
-
rebalance_players!(elo_report)
|
60
|
-
end
|
50
|
+
set_initial_player_scores!
|
51
|
+
eliminate_obvious_bad_players!
|
61
52
|
|
62
|
-
|
53
|
+
while @players.elo_eligible?
|
54
|
+
elo_report = run_elo_round!
|
55
|
+
eliminate_relegation_players!
|
56
|
+
rebalance_players!(elo_report)
|
63
57
|
end
|
64
58
|
|
59
|
+
run_free_for_all!
|
60
|
+
|
65
61
|
sorted_players
|
66
62
|
end
|
67
63
|
|
@@ -72,13 +68,18 @@ module ActiveGenie
|
|
72
68
|
|
73
69
|
def create_players
|
74
70
|
players = PlayersCollection.new(@param_players)
|
75
|
-
players.each { |p|
|
71
|
+
players.each { |p| @config.logger.call({ code: :new_player, player: p.to_h }) }
|
76
72
|
|
77
73
|
players
|
78
74
|
end
|
79
75
|
|
80
76
|
def set_initial_player_scores!
|
81
|
-
RankingScoring.call(
|
77
|
+
RankingScoring.call(
|
78
|
+
@players,
|
79
|
+
@criteria,
|
80
|
+
reviewers: @reviewers,
|
81
|
+
config: @config
|
82
|
+
)
|
82
83
|
end
|
83
84
|
|
84
85
|
def eliminate_obvious_bad_players!
|
@@ -88,7 +89,11 @@ module ActiveGenie
|
|
88
89
|
end
|
89
90
|
|
90
91
|
def run_elo_round!
|
91
|
-
EloRound.call(
|
92
|
+
EloRound.call(
|
93
|
+
@players,
|
94
|
+
@criteria,
|
95
|
+
config: @config
|
96
|
+
)
|
92
97
|
end
|
93
98
|
|
94
99
|
def eliminate_relegation_players!
|
@@ -106,25 +111,27 @@ module ActiveGenie
|
|
106
111
|
end
|
107
112
|
|
108
113
|
def run_free_for_all!
|
109
|
-
FreeForAll.call(
|
114
|
+
FreeForAll.call(
|
115
|
+
@players,
|
116
|
+
@criteria,
|
117
|
+
config: @config
|
118
|
+
)
|
110
119
|
end
|
111
120
|
|
112
121
|
def sorted_players
|
113
122
|
players = @players.sorted
|
114
|
-
|
123
|
+
@config.logger.call({ ranking_id:, code: :ranking_final, players: players.map(&:to_h) })
|
115
124
|
|
116
125
|
players.map(&:to_h)
|
117
126
|
end
|
118
127
|
|
119
|
-
def log_context
|
120
|
-
{ ranking_id: }
|
121
|
-
end
|
122
|
-
|
123
128
|
def ranking_id
|
124
|
-
|
125
|
-
|
129
|
+
@ranking_id ||= begin
|
130
|
+
player_ids = @players.map(&:id).join(',')
|
131
|
+
ranking_unique_key = [player_ids, @criteria, @config.to_json].join('-')
|
126
132
|
|
127
|
-
|
133
|
+
Digest::MD5.hexdigest(ranking_unique_key)
|
134
|
+
end
|
128
135
|
end
|
129
136
|
end
|
130
137
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../scoring/recommended_reviewers'
|
4
|
-
|
5
3
|
module ActiveGenie
|
6
4
|
module Ranking
|
7
5
|
class RankingScoring
|
@@ -9,7 +7,7 @@ module ActiveGenie
|
|
9
7
|
new(...).call
|
10
8
|
end
|
11
9
|
|
12
|
-
def initialize(players, criteria, reviewers: [], config:
|
10
|
+
def initialize(players, criteria, reviewers: [], config: nil)
|
13
11
|
@players = players
|
14
12
|
@criteria = criteria
|
15
13
|
@config = ActiveGenie.configuration.merge(config)
|
@@ -17,12 +15,11 @@ module ActiveGenie
|
|
17
15
|
end
|
18
16
|
|
19
17
|
def call
|
20
|
-
|
21
|
-
|
18
|
+
@config.log.additional_context = { ranking_scoring_id: }
|
19
|
+
@reviewers = generate_reviewers
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
21
|
+
players_without_score.each do |player|
|
22
|
+
player.score = generate_score(player)
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
@@ -40,7 +37,7 @@ module ActiveGenie
|
|
40
37
|
config: @config
|
41
38
|
).values_at('final_score', 'final_reasoning')
|
42
39
|
|
43
|
-
|
40
|
+
@config.logger.call({ code: :new_score, player_id: player.id, score:, reasoning: })
|
44
41
|
|
45
42
|
score
|
46
43
|
end
|
@@ -54,20 +51,18 @@ module ActiveGenie
|
|
54
51
|
config: @config
|
55
52
|
).values_at('reviewer1', 'reviewer2', 'reviewer3')
|
56
53
|
|
57
|
-
|
54
|
+
@config.logger.call({ code: :new_reviewers, reviewers: [reviewer1, reviewer2, reviewer3] })
|
58
55
|
|
59
56
|
[reviewer1, reviewer2, reviewer3]
|
60
57
|
end
|
61
58
|
|
62
|
-
def log_context
|
63
|
-
{ ranking_scoring_id: }
|
64
|
-
end
|
65
|
-
|
66
59
|
def ranking_scoring_id
|
67
|
-
|
68
|
-
|
60
|
+
@ranking_scoring_id ||= begin
|
61
|
+
player_ids = players_without_score.map(&:id).join(',')
|
62
|
+
ranking_unique_key = [player_ids, @criteria, @config.to_json].join('-')
|
69
63
|
|
70
|
-
|
64
|
+
"#{Digest::MD5.hexdigest(ranking_unique_key)}-scoring"
|
65
|
+
end
|
71
66
|
end
|
72
67
|
end
|
73
68
|
end
|
@@ -52,14 +52,14 @@ module ActiveGenie
|
|
52
52
|
|
53
53
|
result['final_score'] = 0 if result['final_score'].nil?
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
55
|
+
@config.logger.call({
|
56
|
+
code: :scoring,
|
57
|
+
text: @text[0..30],
|
58
|
+
criteria: @criteria[0..30],
|
59
|
+
reviewers: reviewers,
|
60
|
+
score: result['final_score'],
|
61
|
+
reasoning: result['final_reasoning']
|
62
|
+
})
|
63
63
|
|
64
64
|
result
|
65
65
|
end
|
@@ -7,7 +7,7 @@ ActiveGenie.configure do |config|
|
|
7
7
|
# config.providers.openai.api_url = 'https://api.openai.com/v1'
|
8
8
|
# config.providers.openai.lower_tier_model = 'gpt-4.1-mini'
|
9
9
|
# config.providers.openai.middle_tier_model = 'gpt-4.1'
|
10
|
-
# config.providers.openai.
|
10
|
+
# config.providers.openai.higher_tier_model = 'o3-mini'
|
11
11
|
# config.providers.openai.client = ActiveGenie::Providers::Openai::Client.new(config)
|
12
12
|
|
13
13
|
# example how add a new provider
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_genie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.26.
|
4
|
+
version: 0.26.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Radamés Roriz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
The lodash for GenAI, stop reinventing the wheel
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- lib/active_genie/clients/providers/google_client.rb
|
36
36
|
- lib/active_genie/clients/providers/openai_client.rb
|
37
37
|
- lib/active_genie/clients/unified_client.rb
|
38
|
+
- lib/active_genie/config/README.md
|
38
39
|
- lib/active_genie/config/battle_config.rb
|
39
40
|
- lib/active_genie/config/data_extractor_config.rb
|
40
41
|
- lib/active_genie/config/llm_config.rb
|
@@ -60,7 +61,6 @@ files:
|
|
60
61
|
- lib/active_genie/logger.rb
|
61
62
|
- lib/active_genie/ranking.rb
|
62
63
|
- lib/active_genie/ranking/README.md
|
63
|
-
- lib/active_genie/ranking/concerns/loggable.rb
|
64
64
|
- lib/active_genie/ranking/elo_round.rb
|
65
65
|
- lib/active_genie/ranking/free_for_all.rb
|
66
66
|
- lib/active_genie/ranking/player.rb
|