fino 1.5.0 → 1.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23a8486cb9d7c402ff499051da385a911437dd8a4d9a49df5712ef3e439f0b0d
4
- data.tar.gz: cdd83bdb9542a59f4c0e4f409e76231a40028acf25e2293de84e45873c296b26
3
+ metadata.gz: 02fd274d08f9e015ac157ee3237c91080af94ecb7b8439153531681acba77572
4
+ data.tar.gz: 42b5dbc517b0fa2919b7896ca2885b280f734c246455685c4957ebb967922094
5
5
  SHA512:
6
- metadata.gz: 59315d14709d165cfe989d66324ca823f8fb13cd8c140246d6bb9542876d49446a9b52654ac15b34b39a7bdb8f9b79bba9e4d065ab8e9d35e2150a3862f32e7d
7
- data.tar.gz: a9fc49c4e631b8a6812ff51401597591886a42e6a354feed62bdd8e308a1ebef66469485fdc83e647ad53e1a057d5860411e5ff4c15193b6a57fe72b7910b041
6
+ metadata.gz: bb7a6d189bd4b25ffc4414a66e98d6bd289c64d2b4ca3fa456fc452165be4d1750d14bf62b5afe71209f0a5ade1a6d76d4413b3600c517e5fb0163cd8d791f6b
7
+ data.tar.gz: ec48c0a0d6012021a1918b2ad5c334bad9256b2199caf63ee6846116216ef7361b8424871a4d85c7dce2d9b716f29c64f0d884accc791dc197097f5d1661dada
data/README.md CHANGED
@@ -74,6 +74,8 @@ Fino.set(model: "gpt-5", at: :openai, overrides: { "qa" => "our_local_model_not_
74
74
 
75
75
  Fino.value(:model, at: :openai) #=> "gpt-5"
76
76
  Fino.value(:model, at: :openai, for: "qa") #=> "our_local_model_not_to_pay_to_sam_altman"
77
+
78
+ Fino.setting(:model, at: :openai).overrides #=> { "qa" => "our_local_model_not_to_pay_to_sam_altman" }
77
79
  ```
78
80
 
79
81
  ### A/B testing
data/lib/fino/cache.rb CHANGED
@@ -1,11 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fino::Cache
4
- def fetch(key, &)
4
+ def exist?(key)
5
+ raise NotImplementedError
6
+ end
7
+
8
+ def read(key)
5
9
  raise NotImplementedError
6
10
  end
7
11
 
8
12
  def write(key, value)
9
13
  raise NotImplementedError
10
14
  end
15
+
16
+ def fetch(key, &block)
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def fetch_multi(*keys, &block)
21
+ raise NotImplementedError
22
+ end
23
+
24
+ def delete(key)
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def clear
29
+ raise NotImplementedError
30
+ end
11
31
  end
@@ -1,25 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Fino::Configuration
4
- attr_reader :registry, :adapter_builder_block, :cache_builder_block, :pipeline_builder_block
4
+ attr_reader :registry, :pipeline_builder_block
5
5
 
6
6
  def initialize(registry)
7
7
  @registry = registry
8
8
  end
9
9
 
10
+ def adapter_builder_block
11
+ @wrapped_adapter_builder_block || @adapter_builder_block
12
+ end
13
+
10
14
  def adapter(&block)
11
15
  @adapter_builder_block = block
12
16
  end
13
17
 
18
+ def wrap_adapter(&block)
19
+ @wrapped_adapter_builder_block = proc { block.call(@adapter_builder_block.call) }
20
+ end
21
+
22
+ def cache_builder_block
23
+ @wrapped_cache_builder_block || @cache_builder_block
24
+ end
25
+
14
26
  def cache(&block)
15
27
  @cache_builder_block = block
16
28
  end
17
29
 
30
+ def wrap_cache(&block)
31
+ @wrapped_cache_builder_block = proc { block.call(@cache_builder_block.call) }
32
+ end
33
+
18
34
  def pipeline(&block)
19
35
  @pipeline_builder_block = block
20
36
  end
21
37
 
22
- def settings(&)
23
- Fino::Registry::DSL.new(registry).instance_eval(&)
38
+ def settings(&block)
39
+ Fino::Registry::DSL.new(registry).instance_eval(&block)
24
40
  end
25
41
  end
@@ -28,7 +28,7 @@ class Fino::Definition::Setting
28
28
  end
29
29
 
30
30
  def default
31
- defined?(@default) ? @default : @default = options[:default]
31
+ defined?(@default) ? @default : @default = type_class.deserialize(options[:default])
32
32
  end
33
33
 
34
34
  def description
data/lib/fino/library.rb CHANGED
@@ -15,6 +15,20 @@ class Fino::Library
15
15
  settings(*setting_names, at: at).map { |s| s.value(**context) }
16
16
  end
17
17
 
18
+ def enabled?(setting_name, at: nil, **context)
19
+ setting = setting(setting_name, at: at)
20
+ raise ArgumentError, "Setting #{setting_name} is not a boolean" unless setting.instance_of?(Fino::Settings::Boolean)
21
+
22
+ setting.enabled?(**context)
23
+ end
24
+
25
+ def disabled?(setting_name, at: nil, **context)
26
+ setting = setting(setting_name, at: at)
27
+ raise ArgumentError, "Setting #{setting_name} is not a boolean" unless setting.instance_of?(Fino::Settings::Boolean)
28
+
29
+ setting.disabled?(**context)
30
+ end
31
+
18
32
  def setting(setting_name, at: nil)
19
33
  pipeline.read(build_setting_definition(setting_name, at: at))
20
34
  end
@@ -9,8 +9,10 @@ class Fino::Pipe::Cache
9
9
  end
10
10
 
11
11
  def read(setting_definition)
12
- cache.fetch(setting_definition.key) do
13
- pipe.read(setting_definition)
12
+ return cache.read(setting_definition.key) if cache.exist?(setting_definition.key)
13
+
14
+ pipe.read(setting_definition).tap do |result|
15
+ cache.write(setting_definition.key, result)
14
16
  end
15
17
  end
16
18
 
data/lib/fino/pipeline.rb CHANGED
@@ -8,26 +8,20 @@ class Fino::Pipeline
8
8
  def initialize(storage, pipes = [])
9
9
  @storage = storage
10
10
  @pipes = pipes
11
- @pipe_wrapper = ->(pipe) { pipe }
12
11
  end
13
12
 
14
- def use(pipe_class, *args, **kwargs, &block)
15
- pipes << ->(pipe) { pipe_class.new(pipe, *args, **kwargs, &block) }
16
- @pipeline = nil
17
- end
18
-
19
- def wrap(&block)
20
- @pipe_wrapper = block
13
+ def use(pipe_class, ...)
14
+ pipes << ->(pipe) { pipe_class.new(pipe, ...) }
21
15
  @pipeline = nil
22
16
  end
23
17
 
24
18
  private
25
19
 
26
- attr_reader :storage, :pipes, :pipe_wrapper
20
+ attr_reader :storage, :pipes
27
21
 
28
22
  def pipeline
29
- @pipeline ||= pipes.inject(pipe_wrapper.call(storage)) do |pipe, builder|
30
- pipe_wrapper.call(builder.call(pipe))
23
+ @pipeline ||= pipes.inject(storage) do |pipe, builder|
24
+ builder.call(pipe)
31
25
  end
32
26
  end
33
27
  end
data/lib/fino/registry.rb CHANGED
@@ -37,7 +37,7 @@ class Fino::Registry
37
37
  )
38
38
  end
39
39
 
40
- def section(section_name, options = {}, &)
40
+ def section(section_name, options = {}, &block)
41
41
  section_definition = Fino::Definition::Section.new(
42
42
  name: section_name,
43
43
  **options
@@ -45,7 +45,7 @@ class Fino::Registry
45
45
 
46
46
  @registry.register_section(section_definition)
47
47
 
48
- SectionDSL.new(section_definition, @registry).instance_eval(&)
48
+ SectionDSL.new(section_definition, @registry).instance_eval(&block)
49
49
  end
50
50
  end
51
51
 
@@ -17,4 +17,12 @@ class Fino::Settings::Boolean
17
17
  end
18
18
  end
19
19
  end
20
+
21
+ def enabled?(**context)
22
+ value(**context)
23
+ end
24
+
25
+ def disabled?(**context)
26
+ !enabled?(**context)
27
+ end
20
28
  end
@@ -9,24 +9,70 @@ module Fino::Settings::Numeric
9
9
  @name = name
10
10
  @short_name = short_name || name
11
11
  end
12
+
13
+ def base_factor
14
+ 1
15
+ end
16
+
17
+ def convertible_to?(_other)
18
+ false
19
+ end
20
+ end
21
+
22
+ module Time
23
+ BASE_UNIT = :seconds
24
+
25
+ def convertible_to?(other)
26
+ other.is_a?(Time)
27
+ end
12
28
  end
13
29
 
14
30
  class Milliseconds < Generic
31
+ include Time
32
+
15
33
  def initialize = super("Milliseconds", "ms")
34
+
35
+ def base_factor
36
+ 0.001
37
+ end
38
+ end
39
+
40
+ class Seconds < Generic
41
+ include Time
42
+
43
+ def initialize = super("Seconds", "sec")
44
+
45
+ def base_factor
46
+ 1
47
+ end
16
48
  end
17
49
 
18
50
  module_function
19
51
 
20
52
  def for(identifier)
21
- case identifier
22
- when :ms
53
+ case identifier.to_s
54
+ when "ms", "milliseconds"
23
55
  Milliseconds.new
56
+ when "sec", "seconds"
57
+ Seconds.new
24
58
  else
25
59
  Generic.new(identifier.to_s.capitalize)
26
60
  end
27
61
  end
28
62
  end
29
63
 
64
+ def value(**context)
65
+ result = super
66
+ return result unless (target_unit_identifier = context[:unit])
67
+
68
+ raise ArgumentError, "No unit defined for this setting" unless unit
69
+
70
+ target_unit = Unit.for(target_unit_identifier)
71
+ raise ArgumentError, "Cannot convert #{unit.name} to #{target_unit.name}" unless unit.convertible_to?(target_unit)
72
+
73
+ result * unit.base_factor / target_unit.base_factor
74
+ end
75
+
30
76
  def unit
31
77
  return unless (identifier = definition.options[:unit])
32
78
 
data/lib/fino/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fino
4
- VERSION = "1.5.0"
4
+ VERSION = "1.6.0"
5
5
  REQUIRED_RUBY_VERSION = ">= 3.0.0"
6
6
  end
data/lib/fino.rb CHANGED
@@ -10,8 +10,7 @@ module Fino
10
10
  end
11
11
 
12
12
  def reset!
13
- Thread.current[:fino_library] = nil
14
-
13
+ @library = nil
15
14
  @registry = nil
16
15
  @configuration = nil
17
16
  end
@@ -22,7 +21,7 @@ module Fino
22
21
  end
23
22
 
24
23
  def library
25
- Thread.current[:fino_library] ||= Fino::Library.new(configuration)
24
+ @library ||= Fino::Library.new(configuration)
26
25
  end
27
26
 
28
27
  def registry
@@ -40,6 +39,8 @@ module Fino
40
39
  def_delegators :library,
41
40
  :value,
42
41
  :values,
42
+ :enabled?,
43
+ :disabled?,
43
44
  :setting,
44
45
  :settings,
45
46
  :slice,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fino
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Egor Iskrenkov