active_genie 0.0.24 → 0.0.25
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 +35 -50
- data/VERSION +1 -1
- data/lib/active_genie/battle/README.md +5 -5
- data/lib/active_genie/battle/generalist.rb +132 -0
- data/lib/active_genie/battle.rb +6 -5
- data/lib/active_genie/clients/providers/anthropic_client.rb +77 -0
- data/lib/active_genie/clients/{base_client.rb → providers/base_client.rb} +74 -100
- data/lib/active_genie/clients/providers/deepseek_client.rb +91 -0
- data/lib/active_genie/clients/providers/google_client.rb +132 -0
- data/lib/active_genie/clients/providers/openai_client.rb +96 -0
- data/lib/active_genie/clients/unified_client.rb +42 -12
- data/lib/active_genie/concerns/loggable.rb +11 -23
- data/lib/active_genie/config/battle_config.rb +8 -0
- data/lib/active_genie/config/data_extractor_config.rb +23 -0
- data/lib/active_genie/config/llm_config.rb +36 -0
- data/lib/active_genie/config/log_config.rb +44 -0
- data/lib/active_genie/config/providers/anthropic_config.rb +57 -0
- data/lib/active_genie/config/providers/deepseek_config.rb +50 -0
- data/lib/active_genie/config/providers/google_config.rb +52 -0
- data/lib/active_genie/config/providers/openai_config.rb +50 -0
- data/lib/active_genie/config/providers/provider_base.rb +89 -0
- data/lib/active_genie/config/providers_config.rb +62 -0
- data/lib/active_genie/config/ranking_config.rb +21 -0
- data/lib/active_genie/config/scoring_config.rb +8 -0
- data/lib/active_genie/configuration.rb +51 -28
- data/lib/active_genie/data_extractor/README.md +13 -13
- data/lib/active_genie/data_extractor/from_informal.rb +54 -48
- data/lib/active_genie/data_extractor/generalist.md +12 -0
- data/lib/active_genie/data_extractor/generalist.rb +125 -0
- data/lib/active_genie/data_extractor.rb +7 -5
- data/lib/active_genie/errors/invalid_provider_error.rb +41 -0
- data/lib/active_genie/logger.rb +17 -66
- data/lib/active_genie/ranking/README.md +31 -1
- data/lib/active_genie/ranking/elo_round.rb +107 -104
- data/lib/active_genie/ranking/free_for_all.rb +78 -74
- data/lib/active_genie/ranking/player.rb +79 -71
- data/lib/active_genie/ranking/players_collection.rb +83 -71
- data/lib/active_genie/ranking/ranking.rb +71 -94
- data/lib/active_genie/ranking/ranking_scoring.rb +71 -50
- data/lib/active_genie/ranking.rb +2 -0
- data/lib/active_genie/scoring/README.md +4 -4
- data/lib/active_genie/scoring/generalist.rb +171 -0
- data/lib/active_genie/scoring/recommended_reviewers.rb +70 -71
- data/lib/active_genie/scoring.rb +8 -5
- data/lib/active_genie.rb +23 -1
- data/lib/tasks/benchmark.rake +10 -9
- data/lib/tasks/install.rake +3 -1
- data/lib/tasks/templates/active_genie.rb +11 -6
- metadata +31 -22
- data/lib/active_genie/battle/basic.rb +0 -129
- data/lib/active_genie/clients/anthropic_client.rb +0 -84
- data/lib/active_genie/clients/google_client.rb +0 -135
- data/lib/active_genie/clients/helpers/retry.rb +0 -29
- data/lib/active_genie/clients/openai_client.rb +0 -98
- data/lib/active_genie/configuration/log_config.rb +0 -14
- data/lib/active_genie/configuration/providers/anthropic_config.rb +0 -54
- data/lib/active_genie/configuration/providers/base_config.rb +0 -85
- data/lib/active_genie/configuration/providers/deepseek_config.rb +0 -54
- data/lib/active_genie/configuration/providers/google_config.rb +0 -56
- data/lib/active_genie/configuration/providers/internal_company_api_config.rb +0 -54
- data/lib/active_genie/configuration/providers/openai_config.rb +0 -54
- data/lib/active_genie/configuration/providers_config.rb +0 -40
- data/lib/active_genie/configuration/runtime_config.rb +0 -35
- data/lib/active_genie/data_extractor/basic.rb +0 -101
- data/lib/active_genie/scoring/basic.rb +0 -170
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveGenie
|
2
4
|
module Concerns
|
3
5
|
module Loggable
|
@@ -6,38 +8,24 @@ module ActiveGenie
|
|
6
8
|
end
|
7
9
|
|
8
10
|
module ClassMethods
|
9
|
-
def
|
11
|
+
def call_with_log_context(context_method)
|
10
12
|
original_method = instance_method(:call)
|
11
|
-
|
13
|
+
|
12
14
|
define_method(:call) do |*args, **kwargs, &block|
|
13
15
|
context = send(context_method, *args, **kwargs)
|
14
|
-
|
15
|
-
|
16
|
-
ActiveGenie::Logger.with_context(context, observer: bound_observer) do
|
16
|
+
|
17
|
+
ActiveGenie::Logger.with_context(context) do
|
17
18
|
original_method.bind(self).call(*args, **kwargs, &block)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def info(log)
|
24
|
-
::ActiveGenie::Logger.info(log)
|
25
|
-
end
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def warn(log)
|
32
|
-
::ActiveGenie::Logger.warn(log)
|
33
|
-
end
|
23
|
+
def logger(data)
|
24
|
+
log = ActiveGenie::Logger.call(data)
|
25
|
+
@config&.log&.call_observers(log)
|
34
26
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
def trace(log)
|
40
|
-
::ActiveGenie::Logger.trace(log)
|
27
|
+
log
|
28
|
+
end
|
41
29
|
end
|
42
30
|
end
|
43
31
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveGenie
|
4
|
+
module Config
|
5
|
+
class DataExtractorConfig
|
6
|
+
attr_accessor :with_explanation, :min_accuracy, :verbose
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@with_explanation = true
|
10
|
+
@min_accuracy = 70
|
11
|
+
@verbose = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def merge(config_params = {})
|
15
|
+
dup.tap do |config|
|
16
|
+
config.with_explanation = config_params[:with_explanation] if config_params[:with_explanation]
|
17
|
+
config.min_accuracy = config_params[:min_accuracy] if config_params[:min_accuracy]
|
18
|
+
config.verbose = config_params[:verbose] if config_params[:verbose]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveGenie
|
4
|
+
module Config
|
5
|
+
class LlmConfig
|
6
|
+
attr_accessor :model, :temperature, :max_tokens, :max_retries, :retry_delay,
|
7
|
+
:model_tier, :read_timeout, :open_timeout, :client
|
8
|
+
attr_reader :provider
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@model = nil
|
12
|
+
@provider = nil
|
13
|
+
@client = nil
|
14
|
+
@temperature = 0
|
15
|
+
@max_tokens = 4096
|
16
|
+
@max_retries = nil
|
17
|
+
@retry_delay = nil
|
18
|
+
@model_tier = 'lower_tier'
|
19
|
+
@read_timeout = nil
|
20
|
+
@open_timeout = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def provider=(provider)
|
24
|
+
@provider = provider&.to_s&.downcase&.strip&.to_sym
|
25
|
+
end
|
26
|
+
|
27
|
+
def merge(config_params = {})
|
28
|
+
dup.tap do |config|
|
29
|
+
config_params.each do |key, value|
|
30
|
+
config.send("#{key}=", value) if config.respond_to?("#{key}=")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveGenie
|
4
|
+
module Config
|
5
|
+
class LogConfig
|
6
|
+
def add_observer(observers: [], scope: nil, &block)
|
7
|
+
@observers ||= []
|
8
|
+
|
9
|
+
raise ArgumentError, 'Scope must be a hash' if !scope.nil? && !scope.is_a?(Hash)
|
10
|
+
|
11
|
+
@observers << { observer: block, scope: scope || {} } if block_given?
|
12
|
+
Array(observers).each do |observer|
|
13
|
+
@observers << { observer:, scope: scope || {} }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def remove_observer(observers)
|
18
|
+
Array(observers).each do |observer|
|
19
|
+
@observers.delete_if { |obs| obs[:observer] == observer }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear_observers
|
24
|
+
@observers = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def call_observers(log)
|
28
|
+
Array(@observers).each do |obs|
|
29
|
+
next unless obs[:scope].all? { |key, value| log[key.to_sym] == value }
|
30
|
+
|
31
|
+
obs[:observer].call(log)
|
32
|
+
rescue StandardError => e
|
33
|
+
ActiveGenie::Logger.call(code: :observer_error, **obs, error: e.message)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def merge(config_params = {})
|
38
|
+
dup.tap do |config|
|
39
|
+
config.add_observer(config_params[:observers]) if config_params[:observers]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './provider_base'
|
4
|
+
|
5
|
+
module ActiveGenie
|
6
|
+
module Config
|
7
|
+
module Providers
|
8
|
+
# Configuration class for the Anthropic API client.
|
9
|
+
# Manages API keys, URLs, model selections, and client instantiation.
|
10
|
+
class AnthropicConfig < ProviderBase
|
11
|
+
NAME = :anthropic
|
12
|
+
|
13
|
+
# Retrieves the API key.
|
14
|
+
# Falls back to the ANTHROPIC_API_KEY environment variable if not set.
|
15
|
+
# @return [String, nil] The API key.
|
16
|
+
def api_key
|
17
|
+
@api_key || ENV['ANTHROPIC_API_KEY']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves the base API URL for Anthropic API.
|
21
|
+
# Defaults to 'https://api.anthropic.com'.
|
22
|
+
# @return [String] The API base URL.
|
23
|
+
def api_url
|
24
|
+
@api_url || 'https://api.anthropic.com'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Retrieves the Anthropic version.
|
28
|
+
# Defaults to '2023-06-01'.
|
29
|
+
# @return [String] The Anthropic version.
|
30
|
+
def anthropic_version
|
31
|
+
@anthropic_version || '2023-06-01'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Retrieves the model name designated for the lower tier (e.g., cost-effective, faster).
|
35
|
+
# Defaults to 'claude-3-haiku'.
|
36
|
+
# @return [String] The lower tier model name.
|
37
|
+
def lower_tier_model
|
38
|
+
@lower_tier_model || 'claude-3-5-haiku-20241022'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Retrieves the model name designated for the middle tier (e.g., balanced performance).
|
42
|
+
# Defaults to 'claude-3-sonnet'.
|
43
|
+
# @return [String] The middle tier model name.
|
44
|
+
def middle_tier_model
|
45
|
+
@middle_tier_model || 'claude-3-7-sonnet-20250219'
|
46
|
+
end
|
47
|
+
|
48
|
+
# Retrieves the model name designated for the upper tier (e.g., most capable).
|
49
|
+
# Defaults to 'claude-3-opus'.
|
50
|
+
# @return [String] The upper tier model name.
|
51
|
+
def upper_tier_model
|
52
|
+
@upper_tier_model || 'claude-3-opus-20240229'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './provider_base'
|
4
|
+
|
5
|
+
module ActiveGenie
|
6
|
+
module Config
|
7
|
+
module Providers
|
8
|
+
# Configuration class for the DeepSeek API client.
|
9
|
+
# Manages API keys, organization IDs, URLs, model selections, and client instantiation.
|
10
|
+
class DeepseekConfig < ProviderBase
|
11
|
+
NAME = :deepseek
|
12
|
+
|
13
|
+
# Retrieves the API key.
|
14
|
+
# Falls back to the DEEPSEEK_API_KEY environment variable if not set.
|
15
|
+
# @return [String, nil] The API key.
|
16
|
+
def api_key
|
17
|
+
@api_key || ENV['DEEPSEEK_API_KEY']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves the base API URL for DeepSeek API.
|
21
|
+
# Defaults to 'https://api.deepseek.com/v1'.
|
22
|
+
# @return [String] The API base URL.
|
23
|
+
def api_url
|
24
|
+
@api_url || 'https://api.deepseek.com/v1'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Retrieves the model name designated for the lower tier (e.g., cost-effective, faster).
|
28
|
+
# Defaults to 'deepseek-chat'.
|
29
|
+
# @return [String] The lower tier model name.
|
30
|
+
def lower_tier_model
|
31
|
+
@lower_tier_model || 'deepseek-chat'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Retrieves the model name designated for the middle tier (e.g., balanced performance).
|
35
|
+
# Defaults to 'deepseek-chat'.
|
36
|
+
# @return [String] The middle tier model name.
|
37
|
+
def middle_tier_model
|
38
|
+
@middle_tier_model || 'deepseek-chat'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Retrieves the model name designated for the upper tier (e.g., most capable).
|
42
|
+
# Defaults to 'deepseek-reasoner'.
|
43
|
+
# @return [String] The upper tier model name.
|
44
|
+
def upper_tier_model
|
45
|
+
@upper_tier_model || 'deepseek-reasoner'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './provider_base'
|
4
|
+
|
5
|
+
module ActiveGenie
|
6
|
+
module Config
|
7
|
+
module Providers
|
8
|
+
# Configuration class for the Google Generative Language API client.
|
9
|
+
# Manages API keys, URLs, model selections, and client instantiation.
|
10
|
+
class GoogleConfig < ProviderBase
|
11
|
+
NAME = :google
|
12
|
+
|
13
|
+
# Retrieves the API key.
|
14
|
+
# Falls back to the GENERATIVE_LANGUAGE_GOOGLE_API_KEY environment variable if not set.
|
15
|
+
# @return [String, nil] The API key.
|
16
|
+
def api_key
|
17
|
+
@api_key || ENV['GENERATIVE_LANGUAGE_GOOGLE_API_KEY'] || ENV['GEMINI_API_KEY']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves the base API URL for Google Generative Language API.
|
21
|
+
# Defaults to 'https://generativelanguage.googleapis.com'.
|
22
|
+
# @return [String] The API base URL.
|
23
|
+
def api_url
|
24
|
+
# NOTE: Google Generative Language API uses a specific path structure like /v1beta/models/{model}:generateContent
|
25
|
+
# The base URL here should be just the domain part.
|
26
|
+
@api_url || 'https://generativelanguage.googleapis.com'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Retrieves the model name designated for the lower tier (e.g., cost-effective, faster).
|
30
|
+
# Defaults to 'gemini-2.0-flash-lite'.
|
31
|
+
# @return [String] The lower tier model name.
|
32
|
+
def lower_tier_model
|
33
|
+
@lower_tier_model || 'gemini-2.0-flash-lite'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Retrieves the model name designated for the middle tier (e.g., balanced performance).
|
37
|
+
# Defaults to 'gemini-2.0-flash'.
|
38
|
+
# @return [String] The middle tier model name.
|
39
|
+
def middle_tier_model
|
40
|
+
@middle_tier_model || 'gemini-2.0-flash'
|
41
|
+
end
|
42
|
+
|
43
|
+
# Retrieves the model name designated for the upper tier (e.g., most capable).
|
44
|
+
# Defaults to 'gemini-2.5-pro-experimental'.
|
45
|
+
# @return [String] The upper tier model name.
|
46
|
+
def upper_tier_model
|
47
|
+
@upper_tier_model || 'gemini-2.5-pro-experimental'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './provider_base'
|
4
|
+
|
5
|
+
module ActiveGenie
|
6
|
+
module Config
|
7
|
+
module Providers
|
8
|
+
# Configuration class for the OpenAI API client.
|
9
|
+
# Manages API keys, organization IDs, URLs, model selections, and client instantiation.
|
10
|
+
class OpenaiConfig < ProviderBase
|
11
|
+
NAME = :openai
|
12
|
+
|
13
|
+
# Retrieves the API key.
|
14
|
+
# Falls back to the OPENAI_API_KEY environment variable if not set.
|
15
|
+
# @return [String, nil] The API key.
|
16
|
+
def api_key
|
17
|
+
@api_key || ENV['OPENAI_API_KEY']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieves the base API URL for OpenAI API.
|
21
|
+
# Defaults to 'https://api.openai.com/v1'.
|
22
|
+
# @return [String] The API base URL.
|
23
|
+
def api_url
|
24
|
+
@api_url || 'https://api.openai.com/v1'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Retrieves the model name designated for the lower tier (e.g., cost-effective, faster).
|
28
|
+
# Defaults to 'gpt-4o-mini'.
|
29
|
+
# @return [String] The lower tier model name.
|
30
|
+
def lower_tier_model
|
31
|
+
@lower_tier_model || 'gpt-4.1-mini'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Retrieves the model name designated for the middle tier (e.g., balanced performance).
|
35
|
+
# Defaults to 'gpt-4o'.
|
36
|
+
# @return [String] The middle tier model name.
|
37
|
+
def middle_tier_model
|
38
|
+
@middle_tier_model || 'gpt-4.1'
|
39
|
+
end
|
40
|
+
|
41
|
+
# Retrieves the model name designated for the upper tier (e.g., most capable).
|
42
|
+
# Defaults to 'o1-preview'.
|
43
|
+
# @return [String] The upper tier model name.
|
44
|
+
def upper_tier_model
|
45
|
+
@upper_tier_model || 'o3-mini'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveGenie
|
4
|
+
module Config
|
5
|
+
module Providers
|
6
|
+
class ProviderBase
|
7
|
+
NAME = :unknown
|
8
|
+
|
9
|
+
attr_writer :api_key, :organization, :api_url, :client,
|
10
|
+
:lower_tier_model, :middle_tier_model, :upper_tier_model
|
11
|
+
|
12
|
+
# Maps a symbolic tier (:lower_tier, :middle_tier, :upper_tier) to a specific model name.
|
13
|
+
# Falls back to the lower_tier_model if the tier is nil or unrecognized.
|
14
|
+
# @param tier [Symbol, String, nil] The symbolic tier name.
|
15
|
+
# @return [String] The corresponding model name.
|
16
|
+
def tier_to_model(tier)
|
17
|
+
{
|
18
|
+
lower_tier: lower_tier_model,
|
19
|
+
middle_tier: middle_tier_model,
|
20
|
+
upper_tier: upper_tier_model
|
21
|
+
}[tier&.to_sym] || lower_tier_model
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a hash representation of the configuration.
|
25
|
+
# @param config [Hash] Additional key-value pairs to merge into the hash.
|
26
|
+
# @return [Hash] The configuration settings as a hash.
|
27
|
+
def to_h(config = {})
|
28
|
+
{
|
29
|
+
name: NAME,
|
30
|
+
api_key:,
|
31
|
+
api_url:,
|
32
|
+
lower_tier_model:,
|
33
|
+
middle_tier_model:,
|
34
|
+
upper_tier_model:,
|
35
|
+
**config
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
# Validates the configuration.
|
40
|
+
# @return [Boolean] True if the configuration is valid, false otherwise.
|
41
|
+
def valid?
|
42
|
+
api_key && api_url
|
43
|
+
end
|
44
|
+
|
45
|
+
# Retrieves the API key.
|
46
|
+
# Falls back to the OPENAI_API_KEY environment variable if not set.
|
47
|
+
# @return [String, nil] The API key.
|
48
|
+
def api_key
|
49
|
+
raise NotImplementedError, 'Subclasses must implement this method'
|
50
|
+
end
|
51
|
+
|
52
|
+
# Retrieves the base API URL for OpenAI API.
|
53
|
+
# Defaults to 'https://api.openai.com/v1'.
|
54
|
+
# @return [String] The API base URL.
|
55
|
+
def api_url
|
56
|
+
raise NotImplementedError, 'Subclasses must implement this method'
|
57
|
+
end
|
58
|
+
|
59
|
+
# Lazily initializes and returns an instance of the OpenaiClient.
|
60
|
+
# Passes itself (the config object) to the client's constructor.
|
61
|
+
# @return [ActiveGenie::Clients::OpenaiClient] The client instance.
|
62
|
+
def client
|
63
|
+
raise NotImplementedError, 'Subclasses must implement this method'
|
64
|
+
end
|
65
|
+
|
66
|
+
# Retrieves the model name designated for the lower tier (e.g., cost-effective, faster).
|
67
|
+
# Defaults to 'gpt-4o-mini'.
|
68
|
+
# @return [String] The lower tier model name.
|
69
|
+
def lower_tier_model
|
70
|
+
raise NotImplementedError, 'Subclasses must implement this method'
|
71
|
+
end
|
72
|
+
|
73
|
+
# Retrieves the model name designated for the middle tier (e.g., balanced performance).
|
74
|
+
# Defaults to 'gpt-4o'.
|
75
|
+
# @return [String] The middle tier model name.
|
76
|
+
def middle_tier_model
|
77
|
+
raise NotImplementedError, 'Subclasses must implement this method'
|
78
|
+
end
|
79
|
+
|
80
|
+
# Retrieves the model name designated for the upper tier (e.g., most capable).
|
81
|
+
# Defaults to 'o1-preview'.
|
82
|
+
# @return [String] The upper tier model name.
|
83
|
+
def upper_tier_model
|
84
|
+
raise NotImplementedError, 'Subclasses must implement this method'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveGenie
|
4
|
+
module Config
|
5
|
+
class ProvidersConfig
|
6
|
+
def initialize
|
7
|
+
@all = {}
|
8
|
+
@default = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :all
|
12
|
+
|
13
|
+
def default
|
14
|
+
@default || valid.keys.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def default=(provider)
|
18
|
+
normalized_provider = provider.to_s.downcase.strip
|
19
|
+
@default = normalized_provider.size > 0 ? normalized_provider : valid.keys.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid
|
23
|
+
valid_provider_keys = @all.keys.select { |k| @all[k].valid? }
|
24
|
+
@all.slice(*valid_provider_keys)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add(provider_classes)
|
28
|
+
@all ||= {}
|
29
|
+
Array(provider_classes).each do |provider|
|
30
|
+
name = provider::NAME
|
31
|
+
remove([name]) if @all.key?(name)
|
32
|
+
|
33
|
+
@all[name] = provider.new
|
34
|
+
end
|
35
|
+
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def remove(provider_classes)
|
40
|
+
Array(provider_classes).each do |provider|
|
41
|
+
@all.delete(provider::NAME)
|
42
|
+
end
|
43
|
+
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def merge(config_params = {})
|
48
|
+
dup.tap do |config|
|
49
|
+
config.add(config_params[:providers]) if config_params[:providers]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def method_missing(m, *args, &block)
|
54
|
+
@all[m] || super
|
55
|
+
end
|
56
|
+
|
57
|
+
def respond_to_missing?(m, include_private = false)
|
58
|
+
@all.key?(m) || super
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveGenie
|
4
|
+
module Config
|
5
|
+
class RankingConfig
|
6
|
+
attr_accessor :score_variation_threshold
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@score_variation_threshold = 30
|
10
|
+
end
|
11
|
+
|
12
|
+
def merge(config_params = {})
|
13
|
+
dup.tap do |config|
|
14
|
+
if config_params[:score_variation_threshold]
|
15
|
+
config.score_variation_threshold = config_params[:score_variation_threshold]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,42 +1,65 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'config/providers_config'
|
4
|
+
require_relative 'config/log_config'
|
5
|
+
require_relative 'config/ranking_config'
|
6
|
+
require_relative 'config/scoring_config'
|
7
|
+
require_relative 'config/data_extractor_config'
|
8
|
+
require_relative 'config/battle_config'
|
9
|
+
require_relative 'config/llm_config'
|
8
10
|
|
9
11
|
module ActiveGenie
|
10
|
-
|
11
|
-
|
12
|
+
class Configuration
|
13
|
+
def log
|
14
|
+
@log ||= Config::LogConfig.new
|
15
|
+
end
|
12
16
|
|
13
17
|
def providers
|
14
|
-
@providers ||=
|
15
|
-
p = ProvidersConfig.new
|
16
|
-
p.register(ActiveGenie::Configuration::Providers::OpenaiConfig)
|
17
|
-
p.register(ActiveGenie::Configuration::Providers::GoogleConfig)
|
18
|
-
p.register(ActiveGenie::Configuration::Providers::AnthropicConfig)
|
19
|
-
p.register(ActiveGenie::Configuration::Providers::DeepseekConfig)
|
20
|
-
p
|
21
|
-
end
|
18
|
+
@providers ||= Config::ProvidersConfig.new
|
22
19
|
end
|
23
20
|
|
24
|
-
def
|
25
|
-
@
|
21
|
+
def ranking
|
22
|
+
@ranking ||= Config::RankingConfig.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def scoring
|
26
|
+
@scoring ||= Config::ScoringConfig.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def data_extractor
|
30
|
+
@data_extractor ||= Config::DataExtractorConfig.new
|
26
31
|
end
|
27
32
|
|
28
|
-
def
|
29
|
-
@
|
33
|
+
def battle
|
34
|
+
@battle ||= Config::BattleConfig.new
|
30
35
|
end
|
31
36
|
|
32
|
-
def
|
33
|
-
|
37
|
+
def llm
|
38
|
+
@llm ||= Config::LlmConfig.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge(config_params = {})
|
42
|
+
return config_params if config_params.is_a?(Configuration)
|
43
|
+
|
44
|
+
new_configuration = dup
|
45
|
+
|
46
|
+
%w[log providers llm ranking scoring data_extractor battle].each do |key|
|
47
|
+
config = new_configuration.send(key)
|
48
|
+
|
49
|
+
next unless config.respond_to?(:merge)
|
34
50
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
51
|
+
new_config = if config_params.key?(key)
|
52
|
+
config.merge(config_params[key])
|
53
|
+
else
|
54
|
+
config.merge(config_params)
|
55
|
+
end
|
56
|
+
|
57
|
+
new_configuration.send("#{key}=", new_config)
|
58
|
+
end
|
59
|
+
|
60
|
+
new_configuration
|
40
61
|
end
|
62
|
+
|
63
|
+
attr_writer :log, :providers, :ranking, :scoring, :data_extractor, :battle, :llm
|
41
64
|
end
|
42
65
|
end
|