nitro_intelligence 4.1.0 → 4.1.1
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/docs/CHANGELOG.md +6 -2
- data/lib/nitro_intelligence/client/client.rb +2 -2
- data/lib/nitro_intelligence/client/handlers/audio_transcription_handler.rb +2 -4
- data/lib/nitro_intelligence/client/handlers/base_handler.rb +9 -0
- data/lib/nitro_intelligence/client/handlers/chat_handler.rb +2 -4
- data/lib/nitro_intelligence/client/handlers/decision_handler.rb +2 -9
- data/lib/nitro_intelligence/client/handlers/image_handler.rb +3 -4
- data/lib/nitro_intelligence/client/handlers/observed/audio_transcription_handler.rb +2 -10
- data/lib/nitro_intelligence/client/handlers/observed/base_handler.rb +23 -0
- data/lib/nitro_intelligence/client/handlers/observed/chat_handler.rb +2 -10
- data/lib/nitro_intelligence/client/handlers/observed/decision_handler.rb +3 -10
- data/lib/nitro_intelligence/client/handlers/observed/image_handler.rb +2 -10
- data/lib/nitro_intelligence/client/handlers/observed/text_to_speech_handler.rb +2 -10
- data/lib/nitro_intelligence/client/handlers/text_to_speech_handler.rb +2 -5
- data/lib/nitro_intelligence/media/image_generation.rb +1 -2
- data/lib/nitro_intelligence/models/model.rb +5 -0
- data/lib/nitro_intelligence/models/model_catalog.rb +15 -0
- data/lib/nitro_intelligence/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0e7cc3cbb0388e9001c106d00fddb60d6e1d7f2c3b9b54aa50d842e9ed719b8f
|
|
4
|
+
data.tar.gz: c1fce6397a2b3bba37ac56531c27608f9e8503e11603c0d9d2634a77dc17937f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c40c5f964e4e9c5441460f7c5113ea4e55d83e73ed9be8cc82c8021a0b8d69772ea8f29a3de6b9a3706557fb8260377bebac2231542cfcbd940ef3973156a6c
|
|
7
|
+
data.tar.gz: ee972990ddda7041e3a756384022e46c68bc3e8af6e5188c545ad559e1c46618b7a1c0a5733940dd093c7a3d73aeb71a2012266de082776a3ec945b32c925067
|
data/docs/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [4.1.1](https://github.com/powerhome/nitro-intelligence.rb/compare/v4.1.0...v4.1.1) (2026-11-05)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
* reject a model of the wrong type before sending a request ([#181](https://github.com/powerhome/nitro-intelligence.rb/issues/181)) ([c84955d](https://github.com/powerhome/nitro-intelligence.rb/commit/c84955d9b3751f1c456ff1e03df48fa962204b7e))
|
|
9
14
|
|
|
10
15
|
## [4.1.0] - 2026-11-04
|
|
11
16
|
|
|
@@ -223,7 +228,6 @@ Each warns through `NitroIntelligence.deprecator`, and is removed in 5.0. See [U
|
|
|
223
228
|
- Require Ruby 3.3 or later (#10)
|
|
224
229
|
- Upgrade langfuse-rb to 0.7.0. (#12)
|
|
225
230
|
|
|
226
|
-
[Unreleased]: https://github.com/powerhome/nitro-intelligence.rb/compare/v4.1.0-nitro_intelligence...HEAD
|
|
227
231
|
[4.1.0]: https://github.com/powerhome/nitro-intelligence.rb/compare/v4.0.0-nitro_intelligence...v4.1.0-nitro_intelligence
|
|
228
232
|
[4.0.0]: https://github.com/powerhome/nitro-intelligence.rb/compare/v3.1.0-nitro_intelligence...v4.0.0-nitro_intelligence
|
|
229
233
|
[3.1.0]: https://github.com/powerhome/nitro-intelligence.rb/compare/v3.0.2-nitro_intelligence...v3.1.0-nitro_intelligence
|
|
@@ -26,8 +26,8 @@ module NitroIntelligence
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# @api private
|
|
29
|
-
def self.validate_model(model)
|
|
30
|
-
|
|
29
|
+
def self.validate_model(model, type: Model)
|
|
30
|
+
NitroIntelligence.model_catalog.fetch(model, type:)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -14,9 +14,7 @@ module NitroIntelligence
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def perform_request(audio_file:, message: "", parameters: {}, correlation_trace_id: nil, mask_content: false)
|
|
17
|
-
|
|
18
|
-
add_correlation_headers(parameters, trace_id: correlation_trace_id)
|
|
19
|
-
add_message_redaction_header(parameters, mask_content:)
|
|
17
|
+
add_gateway_headers(parameters, correlation_trace_id:, mask_content:, modality: "audio")
|
|
20
18
|
@client.audio.transcriptions.create(
|
|
21
19
|
prompt: message,
|
|
22
20
|
file: audio_file,
|
|
@@ -31,7 +29,7 @@ module NitroIntelligence
|
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
parameters.replace(default_parameters.merge(parameters))
|
|
34
|
-
Client.validate_model(parameters[:model])
|
|
32
|
+
Client.validate_model(parameters[:model], type: TextModel)
|
|
35
33
|
end
|
|
36
34
|
end
|
|
37
35
|
end
|
|
@@ -119,6 +119,15 @@ module NitroIntelligence
|
|
|
119
119
|
)
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
+
# Every request to the gateway names the model asked for, and the modality where the
|
|
123
|
+
# route alone does not, carries the correlation headers and, for a project that masks
|
|
124
|
+
# content, asks the gateway to redact it from its logs.
|
|
125
|
+
def add_gateway_headers(parameters, correlation_trace_id:, mask_content:, modality: nil)
|
|
126
|
+
add_request_headers(parameters, MODALITY_HEADER => modality, REQUESTED_MODEL_HEADER => parameters[:model])
|
|
127
|
+
add_correlation_headers(parameters, trace_id: correlation_trace_id)
|
|
128
|
+
add_message_redaction_header(parameters, mask_content:)
|
|
129
|
+
end
|
|
130
|
+
|
|
122
131
|
# A project that masks content in Cerebro keeps it out of the gateway's logs
|
|
123
132
|
# too, so one setting decides where a request's content is recorded.
|
|
124
133
|
def add_message_redaction_header(parameters, mask_content:)
|
|
@@ -14,9 +14,7 @@ module NitroIntelligence
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def perform_request(parameters: {}, correlation_trace_id: nil, mask_content: false)
|
|
17
|
-
|
|
18
|
-
add_correlation_headers(parameters, trace_id: correlation_trace_id)
|
|
19
|
-
add_message_redaction_header(parameters, mask_content:)
|
|
17
|
+
add_gateway_headers(parameters, correlation_trace_id:, mask_content:)
|
|
20
18
|
@client.chat.completions.create(**parameters.slice(*ALLOWED_EXTRA_PARAMETERS))
|
|
21
19
|
end
|
|
22
20
|
|
|
@@ -33,7 +31,7 @@ module NitroIntelligence
|
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
parameters.replace(default_parameters.merge(parameters))
|
|
36
|
-
Client.validate_model(parameters[:model])
|
|
34
|
+
Client.validate_model(parameters[:model], type: TextModel)
|
|
37
35
|
end
|
|
38
36
|
end
|
|
39
37
|
end
|
|
@@ -34,9 +34,7 @@ module NitroIntelligence
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def perform_request(state:, questions:, parameters: {}, correlation_trace_id: nil, mask_content: false)
|
|
37
|
-
|
|
38
|
-
add_correlation_headers(parameters, trace_id: correlation_trace_id)
|
|
39
|
-
add_message_redaction_header(parameters, mask_content:)
|
|
37
|
+
add_gateway_headers(parameters, correlation_trace_id:, mask_content:)
|
|
40
38
|
response = @client.request(
|
|
41
39
|
method: :post,
|
|
42
40
|
path:,
|
|
@@ -54,12 +52,7 @@ module NitroIntelligence
|
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
parameters.replace(default_parameters.merge(parameters))
|
|
57
|
-
Client.validate_model(parameters[:model])
|
|
58
|
-
return if NitroIntelligence.model_catalog.lookup_by_name(parameters[:model]).is_a?(DecisionModel)
|
|
59
|
-
|
|
60
|
-
# A decision request has nothing in common with a chat one, so a model of another type
|
|
61
|
-
# would fail at the gateway with an error that does not say why.
|
|
62
|
-
raise ArgumentError, "Model '#{parameters[:model]}' is not a decision model"
|
|
55
|
+
Client.validate_model(parameters[:model], type: DecisionModel)
|
|
63
56
|
end
|
|
64
57
|
|
|
65
58
|
private
|
|
@@ -21,12 +21,12 @@ module NitroIntelligence
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def perform_request(parameters: {}, correlation_trace_id: nil, mask_content: false)
|
|
24
|
-
|
|
25
|
-
add_correlation_headers(parameters, trace_id: correlation_trace_id)
|
|
26
|
-
add_message_redaction_header(parameters, mask_content:)
|
|
24
|
+
add_gateway_headers(parameters, correlation_trace_id:, mask_content:, modality: "image")
|
|
27
25
|
@client.chat.completions.create(**parameters.slice(*ALLOWED_EXTRA_PARAMETERS))
|
|
28
26
|
end
|
|
29
27
|
|
|
28
|
+
# The model is not checked here: building the ImageGeneration already checked it, along
|
|
29
|
+
# with the aspect ratio and resolution it supports.
|
|
30
30
|
def validate_and_resolve!(parameters, image_generation)
|
|
31
31
|
default_parameters = {
|
|
32
32
|
image_generation:,
|
|
@@ -45,7 +45,6 @@ module NitroIntelligence
|
|
|
45
45
|
# Deep, so that request options a caller passes (headers, max_retries,
|
|
46
46
|
# timeout) sit alongside the image config rather than replacing it.
|
|
47
47
|
parameters.replace(default_parameters.deep_merge(parameters))
|
|
48
|
-
Client.validate_model(parameters[:model])
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
private
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "nitro_intelligence/client/handlers/observed/base_handler"
|
|
1
2
|
require "base64"
|
|
2
3
|
require "nitro_intelligence/media/audio"
|
|
3
4
|
require "nitro_intelligence/observability/prompt_resolver"
|
|
@@ -7,18 +8,13 @@ module NitroIntelligence
|
|
|
7
8
|
module Handlers
|
|
8
9
|
module Observed
|
|
9
10
|
# @api private
|
|
10
|
-
class AudioTranscriptionHandler
|
|
11
|
+
class AudioTranscriptionHandler < BaseHandler
|
|
11
12
|
# Raised by {Client::Base#transcribe_audio} on an observed client when the prompt it names
|
|
12
13
|
# is not a text prompt.
|
|
13
14
|
#
|
|
14
15
|
# @api public
|
|
15
16
|
class ObservedAudioTranscriptionPromptError < StandardError; end
|
|
16
17
|
|
|
17
|
-
def initialize(base_handler:, observer:)
|
|
18
|
-
@base_handler = base_handler
|
|
19
|
-
@observer = observer
|
|
20
|
-
end
|
|
21
|
-
|
|
22
18
|
def create(audio_file:, message: +"", parameters: {})
|
|
23
19
|
@base_handler.validate_and_resolve!(parameters)
|
|
24
20
|
|
|
@@ -39,10 +35,6 @@ module NitroIntelligence
|
|
|
39
35
|
|
|
40
36
|
private
|
|
41
37
|
|
|
42
|
-
def project
|
|
43
|
-
@observer.project_client.project
|
|
44
|
-
end
|
|
45
|
-
|
|
46
38
|
def handle_prompt(message:, parameters:)
|
|
47
39
|
prompt = NitroIntelligence::Observability::PromptResolver.for(
|
|
48
40
|
store: project.prompt_store,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module NitroIntelligence
|
|
2
|
+
module Client
|
|
3
|
+
module Handlers
|
|
4
|
+
module Observed
|
|
5
|
+
# Wraps a handler's request in an observation recorded to the observer's Cerebro project.
|
|
6
|
+
#
|
|
7
|
+
# @api private
|
|
8
|
+
class BaseHandler
|
|
9
|
+
def initialize(base_handler:, observer:)
|
|
10
|
+
@base_handler = base_handler
|
|
11
|
+
@observer = observer
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def project
|
|
17
|
+
@observer.project_client.project
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "nitro_intelligence/client/handlers/observed/base_handler"
|
|
1
2
|
require "nitro_intelligence/observability/prompt_resolver"
|
|
2
3
|
|
|
3
4
|
module NitroIntelligence
|
|
@@ -6,7 +7,7 @@ module NitroIntelligence
|
|
|
6
7
|
# @api private
|
|
7
8
|
module Observed
|
|
8
9
|
# @api private
|
|
9
|
-
class ChatHandler
|
|
10
|
+
class ChatHandler < BaseHandler
|
|
10
11
|
# Raised by {Client::Base#chat} on an observed client when the request carries no user
|
|
11
12
|
# message for the model to answer: the prompt supplies only a system message, and the
|
|
12
13
|
# caller passed no `message`.
|
|
@@ -14,11 +15,6 @@ module NitroIntelligence
|
|
|
14
15
|
# @api public
|
|
15
16
|
class ObservedChatPromptError < StandardError; end
|
|
16
17
|
|
|
17
|
-
def initialize(base_handler:, observer:)
|
|
18
|
-
@base_handler = base_handler
|
|
19
|
-
@observer = observer
|
|
20
|
-
end
|
|
21
|
-
|
|
22
18
|
def create(message: "", parameters: {})
|
|
23
19
|
@base_handler.validate_and_resolve!(parameters, message)
|
|
24
20
|
|
|
@@ -41,10 +37,6 @@ module NitroIntelligence
|
|
|
41
37
|
|
|
42
38
|
private
|
|
43
39
|
|
|
44
|
-
def project
|
|
45
|
-
@observer.project_client.project
|
|
46
|
-
end
|
|
47
|
-
|
|
48
40
|
# A chat completion needs a turn for the model to answer, and it is the model's own
|
|
49
41
|
# chat template that insists on one: Qwen's raises "No user query found in
|
|
50
42
|
# messages." Left to the gateway that costs a round trip and comes back as a 400
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "nitro_intelligence/client/handlers/observed/base_handler"
|
|
2
|
+
|
|
1
3
|
module NitroIntelligence
|
|
2
4
|
module Client
|
|
3
5
|
module Handlers
|
|
@@ -7,12 +9,7 @@ module NitroIntelligence
|
|
|
7
9
|
# powerhome/cerebro#128.
|
|
8
10
|
#
|
|
9
11
|
# @api private
|
|
10
|
-
class DecisionHandler
|
|
11
|
-
def initialize(base_handler:, observer:)
|
|
12
|
-
@base_handler = base_handler
|
|
13
|
-
@observer = observer
|
|
14
|
-
end
|
|
15
|
-
|
|
12
|
+
class DecisionHandler < BaseHandler
|
|
16
13
|
def create(state:, questions:, parameters: {})
|
|
17
14
|
@base_handler.validate_and_resolve!(parameters)
|
|
18
15
|
|
|
@@ -33,10 +30,6 @@ module NitroIntelligence
|
|
|
33
30
|
|
|
34
31
|
private
|
|
35
32
|
|
|
36
|
-
def project
|
|
37
|
-
@observer.project_client.project
|
|
38
|
-
end
|
|
39
|
-
|
|
40
33
|
def workflow(generation:, state:, questions:, parameters:)
|
|
41
34
|
decision = @base_handler.perform_request(
|
|
42
35
|
state:, questions:, parameters:, correlation_trace_id: generation.trace_id,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "nitro_intelligence/client/handlers/observed/base_handler"
|
|
1
2
|
require "nitro_intelligence/media/image_generation"
|
|
2
3
|
require "nitro_intelligence/observability/prompt_resolver"
|
|
3
4
|
|
|
@@ -6,12 +7,7 @@ module NitroIntelligence
|
|
|
6
7
|
module Handlers
|
|
7
8
|
module Observed
|
|
8
9
|
# @api private
|
|
9
|
-
class ImageHandler
|
|
10
|
-
def initialize(base_handler:, observer:)
|
|
11
|
-
@base_handler = base_handler
|
|
12
|
-
@observer = observer
|
|
13
|
-
end
|
|
14
|
-
|
|
10
|
+
class ImageHandler < BaseHandler
|
|
15
11
|
def create(message: "", target_image: nil, reference_images: [], parameters: {})
|
|
16
12
|
image_generation = build_image_generation(message:, target_image:, reference_images:, parameters:)
|
|
17
13
|
|
|
@@ -36,10 +32,6 @@ module NitroIntelligence
|
|
|
36
32
|
|
|
37
33
|
private
|
|
38
34
|
|
|
39
|
-
def project
|
|
40
|
-
@observer.project_client.project
|
|
41
|
-
end
|
|
42
|
-
|
|
43
35
|
def build_image_generation(message:, target_image:, reference_images:, parameters:)
|
|
44
36
|
NitroIntelligence::ImageGeneration.new(message:, target_image:, reference_images:) do |config|
|
|
45
37
|
config.aspect_ratio = parameters[:aspect_ratio] if parameters.key?(:aspect_ratio)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "nitro_intelligence/client/handlers/observed/base_handler"
|
|
1
2
|
require "nitro_intelligence/media/audio"
|
|
2
3
|
require "nitro_intelligence/observability/prompt_resolver"
|
|
3
4
|
|
|
@@ -6,18 +7,13 @@ module NitroIntelligence
|
|
|
6
7
|
module Handlers
|
|
7
8
|
module Observed
|
|
8
9
|
# @api private
|
|
9
|
-
class TextToSpeechHandler
|
|
10
|
+
class TextToSpeechHandler < BaseHandler
|
|
10
11
|
# Raised by {Client::Base#text_to_speech} on an observed client when the prompt it names
|
|
11
12
|
# is not a text prompt.
|
|
12
13
|
#
|
|
13
14
|
# @api public
|
|
14
15
|
class ObservedTextToSpeechPromptError < StandardError; end
|
|
15
16
|
|
|
16
|
-
def initialize(base_handler:, observer:)
|
|
17
|
-
@base_handler = base_handler
|
|
18
|
-
@observer = observer
|
|
19
|
-
end
|
|
20
|
-
|
|
21
17
|
def create(message: "", parameters: {})
|
|
22
18
|
prompt = handle_prompt(parameters:)
|
|
23
19
|
|
|
@@ -39,10 +35,6 @@ module NitroIntelligence
|
|
|
39
35
|
|
|
40
36
|
private
|
|
41
37
|
|
|
42
|
-
def project
|
|
43
|
-
@observer.project_client.project
|
|
44
|
-
end
|
|
45
|
-
|
|
46
38
|
def handle_prompt(parameters:)
|
|
47
39
|
prompt = NitroIntelligence::Observability::PromptResolver.for(
|
|
48
40
|
store: project.prompt_store,
|
|
@@ -14,9 +14,7 @@ module NitroIntelligence
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def perform_request(message: "", parameters: {}, correlation_trace_id: nil, mask_content: false)
|
|
17
|
-
|
|
18
|
-
add_correlation_headers(parameters, trace_id: correlation_trace_id)
|
|
19
|
-
add_message_redaction_header(parameters, mask_content:)
|
|
17
|
+
add_gateway_headers(parameters, correlation_trace_id:, mask_content:, modality: "audio")
|
|
20
18
|
@client.audio.speech.create(
|
|
21
19
|
input: message,
|
|
22
20
|
**parameters.slice(*ALLOWED_EXTRA_PARAMETERS)
|
|
@@ -25,8 +23,7 @@ module NitroIntelligence
|
|
|
25
23
|
|
|
26
24
|
def validate_and_resolve!(parameters)
|
|
27
25
|
model_name = parameters[:model] || NitroIntelligence.model_catalog.default_text_to_speech_model&.name
|
|
28
|
-
model =
|
|
29
|
-
raise ArgumentError, "Unsupported model: '#{model_name}'" unless model
|
|
26
|
+
model = Client.validate_model(model_name, type: TextToSpeechModel)
|
|
30
27
|
|
|
31
28
|
default_parameters = {
|
|
32
29
|
metadata: {},
|
|
@@ -123,8 +123,7 @@ module NitroIntelligence
|
|
|
123
123
|
|
|
124
124
|
def validate_config!
|
|
125
125
|
# Check model supported
|
|
126
|
-
@model = NitroIntelligence.model_catalog.
|
|
127
|
-
raise ArgumentError, "Unsupported model: '#{@config.model}'" unless @model
|
|
126
|
+
@model = NitroIntelligence.model_catalog.fetch(@config.model, type: ImageModel)
|
|
128
127
|
|
|
129
128
|
# Check aspect_ratio supported
|
|
130
129
|
unless @model.aspect_ratios.include?(@config.aspect_ratio)
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
module NitroIntelligence
|
|
2
2
|
# @api private
|
|
3
3
|
class Model
|
|
4
|
+
# What the model is for, as an error names it: "image" for ImageModel, "text-to-speech" for
|
|
5
|
+
# TextToSpeechModel. Taken from the class name, so a new kind of model has one without
|
|
6
|
+
# declaring it.
|
|
7
|
+
def self.kind = name.demodulize.delete_suffix("Model").underscore.dasherize
|
|
8
|
+
|
|
4
9
|
attr_reader :name, :omit_output_fields
|
|
5
10
|
|
|
6
11
|
def initialize(name:, omit_output_fields: [], **)
|
|
@@ -24,6 +24,21 @@ module NitroIntelligence
|
|
|
24
24
|
@models.find { |model| model.name == name }
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# The named model, checked to be of the type a request needs. A model of another type
|
|
28
|
+
# would fail at the gateway, or deep in a handler's own validation, with an error that
|
|
29
|
+
# does not say why.
|
|
30
|
+
def fetch(name, type: Model)
|
|
31
|
+
model = lookup_by_name(name)
|
|
32
|
+
raise ArgumentError, "Unsupported model: '#{name}'" unless model
|
|
33
|
+
|
|
34
|
+
return model if model.is_a?(type)
|
|
35
|
+
|
|
36
|
+
article = type.kind.start_with?(/[aeiou]/) ? "an" : "a"
|
|
37
|
+
raise ArgumentError, "Model '#{name}' is not #{article} #{type.kind} model"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Unused within the gem, which validates through #fetch, but kept for applications that check
|
|
41
|
+
# whether a model is configured before offering it.
|
|
27
42
|
def exists?(name)
|
|
28
43
|
lookup_by_name(name).present?
|
|
29
44
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nitro_intelligence
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.1.
|
|
4
|
+
version: 4.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Igor Artemenko
|
|
@@ -90,6 +90,7 @@ files:
|
|
|
90
90
|
- lib/nitro_intelligence/client/handlers/decision_handler.rb
|
|
91
91
|
- lib/nitro_intelligence/client/handlers/image_handler.rb
|
|
92
92
|
- lib/nitro_intelligence/client/handlers/observed/audio_transcription_handler.rb
|
|
93
|
+
- lib/nitro_intelligence/client/handlers/observed/base_handler.rb
|
|
93
94
|
- lib/nitro_intelligence/client/handlers/observed/chat_handler.rb
|
|
94
95
|
- lib/nitro_intelligence/client/handlers/observed/decision_handler.rb
|
|
95
96
|
- lib/nitro_intelligence/client/handlers/observed/image_handler.rb
|