Class: Kernai::Mock::Provider
- Defined in:
- lib/kernai/mock/provider.rb
Instance Attribute Summary collapse
-
#calls ⇒ Object
readonly
Returns the value of attribute calls.
Instance Method Summary collapse
- #call(messages:, model:, generation: nil, &block) ⇒ Object
- #call_count ⇒ Object
-
#fail_on_step(step, error_class: Kernai::ProviderError, message: 'mock provider failure') ⇒ Object
Schedule an exception at a specific call index (0-based).
-
#generation_at(index) ⇒ Object
GenerationOptions the provider received at call index ‘i`.
-
#initialize ⇒ Provider
constructor
A new instance of Provider.
- #last_call ⇒ Object
-
#messages_at(index) ⇒ Object
Messages the provider received at call index ‘i` (0-based).
-
#on_call(&block) ⇒ Object
Set a dynamic response handler.
- #reset! ⇒ Object
-
#respond_with(*texts) ⇒ Object
Queue a response (consumed in order, last one repeats).
-
#respond_with_script(script) ⇒ Object
Same behavior as ‘respond_with` but indexed by step number for scenarios where associating a response with its step is clearer than positional ordering.
-
#with_token_counter(&block) ⇒ Object
Optional: deterministic token counter used by tests that assert on usage data.
Methods inherited from Provider
#encode, #encode_part, #fallback_for
Constructor Details
#initialize ⇒ Provider
Returns a new instance of Provider.
8 9 10 11 12 13 14 15 16 |
# File 'lib/kernai/mock/provider.rb', line 8 def initialize super @responses = [] @call_count = 0 @calls = [] @on_call = nil @token_provider = nil @failures = {} end |
Instance Attribute Details
#calls ⇒ Object (readonly)
Returns the value of attribute calls.
6 7 8 |
# File 'lib/kernai/mock/provider.rb', line 6 def calls @calls end |
Instance Method Details
#call(messages:, model:, generation: nil, &block) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/kernai/mock/provider.rb', line 65 def call(messages:, model:, generation: nil, &block) @calls << { messages: , model: model, generation: generation } maybe_raise_scheduled_failure started = Process.clock_gettime(Process::CLOCK_MONOTONIC) content = resolve_response(, model) @call_count += 1 content.to_s.each_char { |c| block.call(c) } if block latency_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - started) * 1000).round tokens = @token_provider&.call(, content) || {} LlmResponse.new( content: content, latency_ms: latency_ms, prompt_tokens: tokens[:prompt_tokens], completion_tokens: tokens[:completion_tokens] ) end |
#call_count ⇒ Object
86 87 88 |
# File 'lib/kernai/mock/provider.rb', line 86 def call_count @calls.size end |
#fail_on_step(step, error_class: Kernai::ProviderError, message: 'mock provider failure') ⇒ Object
Schedule an exception at a specific call index (0-based). Lets scenarios exercise provider-error branches deterministically, without reaching for stub libraries. The raised class defaults to Kernai::ProviderError — the same error the base provider contract raises for wiring problems.
60 61 62 63 |
# File 'lib/kernai/mock/provider.rb', line 60 def fail_on_step(step, error_class: Kernai::ProviderError, message: 'mock provider failure') @failures[step] = { class: error_class, message: } self end |
#generation_at(index) ⇒ Object
GenerationOptions the provider received at call index ‘i`.
102 103 104 |
# File 'lib/kernai/mock/provider.rb', line 102 def generation_at(index) @calls.dig(index, :generation) end |
#last_call ⇒ Object
90 91 92 |
# File 'lib/kernai/mock/provider.rb', line 90 def last_call @calls.last end |
#messages_at(index) ⇒ Object
Messages the provider received at call index ‘i` (0-based).
97 98 99 |
# File 'lib/kernai/mock/provider.rb', line 97 def (index) @calls.dig(index, :messages) end |
#on_call(&block) ⇒ Object
Set a dynamic response handler.
42 43 44 45 |
# File 'lib/kernai/mock/provider.rb', line 42 def on_call(&block) @on_call = block self end |
#reset! ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'lib/kernai/mock/provider.rb', line 106 def reset! @responses = [] @call_count = 0 @calls = [] @on_call = nil @token_provider = nil @failures = {} end |
#respond_with(*texts) ⇒ Object
Queue a response (consumed in order, last one repeats).
19 20 21 22 |
# File 'lib/kernai/mock/provider.rb', line 19 def respond_with(*texts) @responses.concat(texts) self end |
#respond_with_script(script) ⇒ Object
Same behavior as ‘respond_with` but indexed by step number for scenarios where associating a response with its step is clearer than positional ordering. Keys must be a contiguous run of non-negative integers starting at 0; missing steps would break the “last response repeats” contract.
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/kernai/mock/provider.rb', line 29 def respond_with_script(script) sorted_keys = script.keys.sort unless sorted_keys == (0..sorted_keys.max.to_i).to_a raise ArgumentError, 'respond_with_script keys must be contiguous non-negative integers starting at 0, ' \ "got #{sorted_keys.inspect}" end @responses = sorted_keys.map { |k| script[k] } self end |
#with_token_counter(&block) ⇒ Object
Optional: deterministic token counter used by tests that assert on usage data. Receives (messages, content) and must return a hash like { prompt_tokens:, completion_tokens: }.
50 51 52 53 |
# File 'lib/kernai/mock/provider.rb', line 50 def with_token_counter(&block) @token_provider = block self end |