nitro_intelligence 3.1.0 → 4.1.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 +4 -4
- data/.yardopts +9 -0
- data/Rakefile +21 -1
- data/docs/ASSISTANTS.md +594 -0
- data/docs/CHANGELOG.md +243 -0
- data/docs/README.md +190 -12
- data/lib/nitro_intelligence/assistant.rb +82 -3
- data/lib/nitro_intelligence/assistant_registry.rb +18 -0
- data/lib/nitro_intelligence/assistants.rb +340 -102
- data/lib/nitro_intelligence/client/base.rb +88 -8
- data/lib/nitro_intelligence/client/client.rb +22 -2
- data/lib/nitro_intelligence/client/factory.rb +12 -3
- data/lib/nitro_intelligence/client/handlers/audio_transcription_handler.rb +3 -1
- data/lib/nitro_intelligence/client/handlers/base_handler.rb +17 -2
- data/lib/nitro_intelligence/client/handlers/chat_handler.rb +3 -1
- data/lib/nitro_intelligence/client/handlers/decision_handler.rb +75 -0
- data/lib/nitro_intelligence/client/handlers/image_handler.rb +6 -2
- data/lib/nitro_intelligence/client/handlers/observed/audio_transcription_handler.rb +30 -12
- data/lib/nitro_intelligence/client/handlers/observed/chat_handler.rb +16 -3
- data/lib/nitro_intelligence/client/handlers/observed/decision_handler.rb +72 -0
- data/lib/nitro_intelligence/client/handlers/observed/image_handler.rb +20 -5
- data/lib/nitro_intelligence/client/handlers/observed/text_to_speech_handler.rb +27 -9
- data/lib/nitro_intelligence/client/handlers/text_to_speech_handler.rb +3 -1
- data/lib/nitro_intelligence/client/observed.rb +8 -0
- data/lib/nitro_intelligence/client/observers/langfuse_observer.rb +35 -7
- data/lib/nitro_intelligence/configuration.rb +48 -0
- data/lib/nitro_intelligence/decision.rb +105 -0
- data/lib/nitro_intelligence/deprecator.rb +10 -0
- data/lib/nitro_intelligence/langfuse_extension.rb +1 -0
- data/lib/nitro_intelligence/langfuse_tracer_provider.rb +7 -6
- data/lib/nitro_intelligence/media/audio.rb +6 -0
- data/lib/nitro_intelligence/media/image.rb +14 -1
- data/lib/nitro_intelligence/media/image_generation.rb +14 -2
- data/lib/nitro_intelligence/media/media.rb +4 -0
- data/lib/nitro_intelligence/models/model.rb +7 -0
- data/lib/nitro_intelligence/models/model_catalog.rb +3 -0
- data/lib/nitro_intelligence/models/model_factory.rb +2 -0
- data/lib/nitro_intelligence/null_cache.rb +2 -0
- data/lib/nitro_intelligence/observability/project.rb +41 -2
- data/lib/nitro_intelligence/observability/project_client.rb +10 -1
- data/lib/nitro_intelligence/observability/project_client_registry.rb +18 -0
- data/lib/nitro_intelligence/observability/prompt.rb +4 -3
- data/lib/nitro_intelligence/observability/prompt_resolver.rb +2 -0
- data/lib/nitro_intelligence/observability/prompt_store.rb +9 -0
- data/lib/nitro_intelligence/observability/upload_handler.rb +3 -1
- data/lib/nitro_intelligence/pending_review.rb +257 -0
- data/lib/nitro_intelligence/railtie.rb +10 -0
- data/lib/nitro_intelligence/reporter.rb +29 -0
- data/lib/nitro_intelligence/review_decision.rb +36 -0
- data/lib/nitro_intelligence/run_result.rb +160 -0
- data/lib/nitro_intelligence/tool_call_review_interrupt.rb +9 -13
- data/lib/nitro_intelligence/tool_call_review_validator.rb +6 -8
- data/lib/nitro_intelligence/trace.rb +8 -0
- data/lib/nitro_intelligence/version.rb +2 -1
- data/lib/nitro_intelligence.rb +40 -0
- metadata +12 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
require "nitro_intelligence/pending_review"
|
|
2
|
+
|
|
3
|
+
module NitroIntelligence
|
|
4
|
+
# The outcome of one `/runs/wait`: either the run ended, possibly with a reply, or it paused on a
|
|
5
|
+
# review.
|
|
6
|
+
#
|
|
7
|
+
# A run has at most one reply: its final message, an AI message with text and no tool calls. Text
|
|
8
|
+
# the model writes alongside tool calls is working text, never the reply. A paused run's last AI
|
|
9
|
+
# message is a draft awaiting review, so `#reply` is nil whenever the run paused; a reply is final
|
|
10
|
+
# only once a run ends without `__interrupt__`.
|
|
11
|
+
class RunResult
|
|
12
|
+
# How the platform delivered the reply through the assistant's delivery tool, read from the
|
|
13
|
+
# reply's `response_metadata.delivery` stamp. `status` is "delivered" (with `result`, what the
|
|
14
|
+
# tool returned, and `delivered_at`), "failed" (with the tool's `error` and `failed_at`), or
|
|
15
|
+
# "pending": the platform stamps a settled reply "pending" just before it delivers it, so a
|
|
16
|
+
# finished run still showing it was cut off before delivery recorded an outcome. Treat a
|
|
17
|
+
# pending reply as not sent; the next customer message removes it and the model answers both. A
|
|
18
|
+
# field the stamp does not carry, or carries as the wrong type, is nil.
|
|
19
|
+
#
|
|
20
|
+
# @!attribute [r] status
|
|
21
|
+
# @return [String, nil] `"delivered"`, `"failed"` or `"pending"`
|
|
22
|
+
# @!attribute [r] tool
|
|
23
|
+
# @return [String, nil] the delivery tool's name
|
|
24
|
+
# @!attribute [r] attempts
|
|
25
|
+
# @return [Integer, nil] how many times the platform called the tool
|
|
26
|
+
# @!attribute [r] error
|
|
27
|
+
# @return [String, nil] the tool's error, when delivery failed
|
|
28
|
+
# @!attribute [r] result
|
|
29
|
+
# @return [Object, nil] what the tool returned, when it succeeded
|
|
30
|
+
# @!attribute [r] delivered_at
|
|
31
|
+
# @return [String, nil] when the reply was delivered, as an ISO 8601 timestamp
|
|
32
|
+
# @!attribute [r] failed_at
|
|
33
|
+
# @return [String, nil] when delivery gave up, as an ISO 8601 timestamp
|
|
34
|
+
Delivery = Struct.new(:status, :tool, :attempts, :error, :result, :delivered_at, :failed_at,
|
|
35
|
+
keyword_init: true) do
|
|
36
|
+
# @return [Boolean] whether the platform delivered the reply
|
|
37
|
+
def delivered?
|
|
38
|
+
status == "delivered"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Boolean] whether delivery failed
|
|
42
|
+
def failed?
|
|
43
|
+
status == "failed"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [Boolean] whether delivery was cut off before it recorded an outcome
|
|
47
|
+
def pending?
|
|
48
|
+
status == "pending"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @api private
|
|
53
|
+
# The `response_metadata.review` type the platform stamps on a draft when it pauses on it.
|
|
54
|
+
PENDING_REVIEW = "pending".freeze
|
|
55
|
+
|
|
56
|
+
# The response exactly as Assistants returned it.
|
|
57
|
+
#
|
|
58
|
+
# @return [Hash]
|
|
59
|
+
attr_reader :raw
|
|
60
|
+
|
|
61
|
+
# @api private
|
|
62
|
+
def initialize(run)
|
|
63
|
+
@raw = run.to_h
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @return [Boolean] whether the run paused for review
|
|
67
|
+
def interrupted?
|
|
68
|
+
Array(raw["__interrupt__"]).any?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# What the paused run is waiting on, or nil when it did not pause.
|
|
72
|
+
#
|
|
73
|
+
# @return [PendingReview, nil]
|
|
74
|
+
def review
|
|
75
|
+
return @review if defined?(@review)
|
|
76
|
+
|
|
77
|
+
@review = PendingReview.from_run(raw)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# The run's messages as Assistants reports them, oldest first.
|
|
81
|
+
#
|
|
82
|
+
# @return [Array<Hash>]
|
|
83
|
+
def messages
|
|
84
|
+
Array(raw["messages"])
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# The text of the run's reply, always a String: content given as blocks is reduced to its text.
|
|
88
|
+
# Nil while the run is paused, and when it ended without one: a rejected draft is removed,
|
|
89
|
+
# leaving a tool result or the human's message last, and an earlier turn's text is never the
|
|
90
|
+
# reply. Blank text is no reply.
|
|
91
|
+
#
|
|
92
|
+
# @return [String, nil]
|
|
93
|
+
def reply
|
|
94
|
+
reply_message && text(reply_message["content"]).presence
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# The reply's delivery, or nil when the reply carries no delivery stamp: no reply, or no
|
|
98
|
+
# delivery tool configured for the assistant.
|
|
99
|
+
#
|
|
100
|
+
# @return [Delivery, nil]
|
|
101
|
+
def delivery
|
|
102
|
+
return @delivery if defined?(@delivery)
|
|
103
|
+
|
|
104
|
+
stamp = reply_message&.dig("response_metadata", "delivery")
|
|
105
|
+
@delivery = stamp.is_a?(Hash) ? build_delivery(stamp) : nil
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# The run's last message, when the run ended and that message is the assistant's reply: an AI
|
|
111
|
+
# message with no tool calls. A draft still stamped as awaiting review is never the reply, even
|
|
112
|
+
# in a response that reports no pause.
|
|
113
|
+
def reply_message
|
|
114
|
+
return nil if interrupted?
|
|
115
|
+
|
|
116
|
+
message = messages.last
|
|
117
|
+
return nil unless message.is_a?(Hash)
|
|
118
|
+
return nil if message["type"].present? && message["type"] != "ai"
|
|
119
|
+
return nil if Array(message["tool_calls"]).any?
|
|
120
|
+
return nil if awaiting_review?(message)
|
|
121
|
+
|
|
122
|
+
message
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def awaiting_review?(message)
|
|
126
|
+
review = message.dig("response_metadata", "review")
|
|
127
|
+
review.is_a?(Hash) && review["type"] == PENDING_REVIEW
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# A message's content is a string, or a list of content blocks. Its text is the string, or the
|
|
131
|
+
# bare strings and `text` blocks joined, as the platform reads it (LangChain's `message.text`);
|
|
132
|
+
# other blocks -- tool use, reasoning, images -- are not part of the reply.
|
|
133
|
+
def text(content)
|
|
134
|
+
return content if content.is_a?(String)
|
|
135
|
+
return nil unless content.is_a?(Array)
|
|
136
|
+
|
|
137
|
+
content.filter_map do |block|
|
|
138
|
+
next block if block.is_a?(String)
|
|
139
|
+
|
|
140
|
+
block["text"] if block.is_a?(Hash) && block["type"] == "text" && block["text"].is_a?(String)
|
|
141
|
+
end.join
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def build_delivery(stamp)
|
|
145
|
+
Delivery.new(
|
|
146
|
+
status: string_or_nil(stamp["status"]),
|
|
147
|
+
tool: string_or_nil(stamp["tool"]),
|
|
148
|
+
attempts: stamp["attempts"].is_a?(Integer) ? stamp["attempts"] : nil,
|
|
149
|
+
error: string_or_nil(stamp["error"]),
|
|
150
|
+
result: stamp["result"],
|
|
151
|
+
delivered_at: string_or_nil(stamp["delivered_at"]),
|
|
152
|
+
failed_at: string_or_nil(stamp["failed_at"])
|
|
153
|
+
)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def string_or_nil(value)
|
|
157
|
+
value.is_a?(String) ? value : nil
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "active_support/core_ext/hash/indifferent_access"
|
|
2
|
+
require "nitro_intelligence/review_decision"
|
|
2
3
|
|
|
3
4
|
module NitroIntelligence
|
|
4
5
|
# The tool calls one interrupt is holding, and the resume payload that answers them.
|
|
@@ -10,6 +11,8 @@ module NitroIntelligence
|
|
|
10
11
|
# Action requests carry no tool call id, and ids are what a review interface works in, so each is
|
|
11
12
|
# matched back onto the tool calls of the thread's last AI message -- the ones the middleware built
|
|
12
13
|
# them from -- to recover the id. The order of `#tool_calls` is the order `decisions` must be in.
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
13
16
|
class ToolCallReviewInterrupt
|
|
14
17
|
def initialize(thread_state)
|
|
15
18
|
@thread_state = thread_state
|
|
@@ -68,14 +71,10 @@ module NitroIntelligence
|
|
|
68
71
|
review = (review || {}).with_indifferent_access
|
|
69
72
|
|
|
70
73
|
case review[:action].to_s
|
|
71
|
-
when "approve"
|
|
72
|
-
|
|
73
|
-
when "
|
|
74
|
-
|
|
75
|
-
when "reject"
|
|
76
|
-
review[:message].nil? ? { "type" => "reject" } : { "type" => "reject", "message" => review[:message] }
|
|
77
|
-
when "respond"
|
|
78
|
-
{ "type" => "respond", "message" => review[:message] }
|
|
74
|
+
when "approve" then ReviewDecision.approve
|
|
75
|
+
when "edit" then ReviewDecision.edit(tool_call["name"], edited_args(tool_call, review))
|
|
76
|
+
when "reject" then ReviewDecision.reject(review[:message])
|
|
77
|
+
when "respond" then ReviewDecision.respond(review[:message])
|
|
79
78
|
else
|
|
80
79
|
raise Assistants::ThreadResumptionError,
|
|
81
80
|
"Tool call #{tool_call['id']} has no review naming `approve`, `edit`, `reject` or `respond`"
|
|
@@ -84,11 +83,8 @@ module NitroIntelligence
|
|
|
84
83
|
|
|
85
84
|
# Edited arguments are merged over the call the model made, so a reviewer changing one of them
|
|
86
85
|
# does not have to restate the rest -- and cannot drop one by omitting it.
|
|
87
|
-
def
|
|
88
|
-
{
|
|
89
|
-
"name" => tool_call["name"],
|
|
90
|
-
"args" => tool_call["args"].merge(review[:args] || {}),
|
|
91
|
-
}
|
|
86
|
+
def edited_args(tool_call, review)
|
|
87
|
+
tool_call["args"].merge(review[:args] || {})
|
|
92
88
|
end
|
|
93
89
|
|
|
94
90
|
def interrupt_value
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "active_support/core_ext/hash/indifferent_access"
|
|
2
|
+
require "nitro_intelligence/review_decision"
|
|
2
3
|
|
|
3
4
|
module NitroIntelligence
|
|
4
5
|
# The reviews a caller submitted, checked against the tool calls the interrupt is holding, before
|
|
@@ -7,6 +8,8 @@ module NitroIntelligence
|
|
|
7
8
|
# Internal to `Assistants#review_tool_calls`, which builds the only instance there is. What
|
|
8
9
|
# `#validate!` takes follows what that method needs and has changed with it before, so it carries
|
|
9
10
|
# no promise to anything calling it directly.
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
10
13
|
class ToolCallReviewValidator
|
|
11
14
|
def validate!(tool_calls:, tool_calls_under_review:)
|
|
12
15
|
tool_calls = normalize_tool_calls(tool_calls)
|
|
@@ -72,15 +75,10 @@ module NitroIntelligence
|
|
|
72
75
|
end
|
|
73
76
|
|
|
74
77
|
def validate_message!(tool_call_id:, review:, required:)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
raise_error!("Review for tool call #{tool_call_id} must include a message") if required
|
|
79
|
-
return
|
|
78
|
+
case ReviewDecision.message_problem(review[:message], required:)
|
|
79
|
+
when :missing then raise_error!("Review for tool call #{tool_call_id} must include a message")
|
|
80
|
+
when :not_string then raise_error!("Message for tool call #{tool_call_id} must be a string")
|
|
80
81
|
end
|
|
81
|
-
|
|
82
|
-
raise_error!("Message for tool call #{tool_call_id} must be a string") unless message.is_a?(String)
|
|
83
|
-
raise_error!("Review for tool call #{tool_call_id} must include a message") if required && message.blank?
|
|
84
82
|
end
|
|
85
83
|
|
|
86
84
|
def validate_completeness!(submitted_tool_call_ids:, tool_calls_under_review:)
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
module NitroIntelligence
|
|
2
|
+
# Trace IDs, for correlating an observed request with what else a host records about it.
|
|
2
3
|
module Trace
|
|
4
|
+
# The ID of the trace a request passing `trace_seed: seed` is recorded under. The same seed
|
|
5
|
+
# always gives the same ID.
|
|
6
|
+
#
|
|
7
|
+
# @param seed [String] the request's `trace_seed`, such as a document's ID
|
|
8
|
+
# @return [String] the trace ID
|
|
9
|
+
# @example
|
|
10
|
+
# NitroIntelligence::Trace.create_id(seed: "document-123")
|
|
3
11
|
def self.create_id(seed:)
|
|
4
12
|
Langfuse::TraceId.create(seed:)
|
|
5
13
|
end
|
data/lib/nitro_intelligence.rb
CHANGED
|
@@ -11,21 +11,54 @@ require "nitro_intelligence/assistants"
|
|
|
11
11
|
require "nitro_intelligence/client/base"
|
|
12
12
|
require "nitro_intelligence/client/client"
|
|
13
13
|
require "nitro_intelligence/configuration"
|
|
14
|
+
require "nitro_intelligence/deprecator"
|
|
14
15
|
require "nitro_intelligence/media/image_generation"
|
|
15
16
|
require "nitro_intelligence/models/model_catalog"
|
|
16
17
|
require "nitro_intelligence/observability/project_client_registry"
|
|
17
18
|
require "nitro_intelligence/reporter"
|
|
18
19
|
|
|
20
|
+
# The Ruby client for the Nitro Intelligence Platform.
|
|
21
|
+
#
|
|
22
|
+
# The public API is everything in this reference not marked `@api private`, and follows Semantic
|
|
23
|
+
# Versioning. `docs/README.md` and `docs/ASSISTANTS.md` are guides to using it, not a list of
|
|
24
|
+
# everything public. What the reference leaves out may change in any release.
|
|
19
25
|
module NitroIntelligence
|
|
26
|
+
# @!attribute [rw] configuration
|
|
27
|
+
# @api private
|
|
28
|
+
# @return [Class<Configuration>]
|
|
20
29
|
mattr_accessor :configuration, default: Configuration
|
|
21
30
|
|
|
22
31
|
class << self
|
|
32
|
+
# @!method configure
|
|
33
|
+
# Sets the configuration, normally once, from an initializer.
|
|
34
|
+
# @yieldparam config [ActiveSupport::Configurable::Configuration] the settings that
|
|
35
|
+
# {Configuration} lists
|
|
36
|
+
# @return [void]
|
|
37
|
+
# @example
|
|
38
|
+
# NitroIntelligence.configure do |config|
|
|
39
|
+
# config.inference_api_key = ENV.fetch("NITRO_INTELLIGENCE_API_KEY")
|
|
40
|
+
# end
|
|
41
|
+
# @!method config
|
|
42
|
+
# The current configuration.
|
|
43
|
+
# @return [ActiveSupport::Configurable::Configuration] the settings that {Configuration} lists
|
|
44
|
+
# @!method logger
|
|
45
|
+
# @api private
|
|
46
|
+
# @!method environment
|
|
47
|
+
# @api private
|
|
23
48
|
delegate :configure, :config, :logger, :environment, to: :configuration
|
|
24
49
|
|
|
25
50
|
# A registry addressable by name when `assistants_config` carries `definitions`, and the
|
|
26
51
|
# single pre-registry client otherwise. The two shapes are mutually exclusive, so the
|
|
27
52
|
# configuration decides which one a host gets: one that has not reshaped its config keeps
|
|
28
53
|
# the client it already had.
|
|
54
|
+
#
|
|
55
|
+
# @return [AssistantRegistry, Assistants]
|
|
56
|
+
# @raise [ArgumentError] without `definitions`, when `assistants_config` has no `api_key`, as
|
|
57
|
+
# it does by default
|
|
58
|
+
# @raise [Assistants::ConfigurationError] without `definitions`, when `assistants_config`
|
|
59
|
+
# has a blank `api_key` or `user_id`
|
|
60
|
+
# @example
|
|
61
|
+
# NitroIntelligence.assistants["candidate-concierge"].run(thread_id:, messages:)
|
|
29
62
|
def assistants
|
|
30
63
|
current = configuration.assistants_config.to_h.deep_stringify_keys
|
|
31
64
|
return AssistantRegistry.new(current) if current.key?(AssistantRegistry::DEFINITIONS_KEY)
|
|
@@ -33,14 +66,19 @@ module NitroIntelligence
|
|
|
33
66
|
Assistants.new(**current.symbolize_keys)
|
|
34
67
|
end
|
|
35
68
|
|
|
69
|
+
# @api private
|
|
36
70
|
def cache
|
|
37
71
|
configuration.cache_provider
|
|
38
72
|
end
|
|
39
73
|
|
|
74
|
+
# @api private
|
|
40
75
|
def model_catalog
|
|
41
76
|
@model_catalog ||= ModelCatalog.new(configuration.model_config)
|
|
42
77
|
end
|
|
43
78
|
|
|
79
|
+
# Each Cerebro project's client.
|
|
80
|
+
#
|
|
81
|
+
# @return [Observability::ProjectClientRegistry]
|
|
44
82
|
def project_client_registry
|
|
45
83
|
@project_client_registry ||= Observability::ProjectClientRegistry.new(
|
|
46
84
|
base_url: configuration.observability_base_url
|
|
@@ -48,3 +86,5 @@ module NitroIntelligence
|
|
|
48
86
|
end
|
|
49
87
|
end
|
|
50
88
|
end
|
|
89
|
+
|
|
90
|
+
require "nitro_intelligence/railtie" if defined?(Rails::Railtie)
|
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
|
+
version: 4.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Igor Artemenko
|
|
@@ -72,7 +72,10 @@ executables: []
|
|
|
72
72
|
extensions: []
|
|
73
73
|
extra_rdoc_files: []
|
|
74
74
|
files:
|
|
75
|
+
- ".yardopts"
|
|
75
76
|
- Rakefile
|
|
77
|
+
- docs/ASSISTANTS.md
|
|
78
|
+
- docs/CHANGELOG.md
|
|
76
79
|
- docs/README.md
|
|
77
80
|
- lib/nitro_intelligence.rb
|
|
78
81
|
- lib/nitro_intelligence/assistant.rb
|
|
@@ -84,15 +87,19 @@ files:
|
|
|
84
87
|
- lib/nitro_intelligence/client/handlers/audio_transcription_handler.rb
|
|
85
88
|
- lib/nitro_intelligence/client/handlers/base_handler.rb
|
|
86
89
|
- lib/nitro_intelligence/client/handlers/chat_handler.rb
|
|
90
|
+
- lib/nitro_intelligence/client/handlers/decision_handler.rb
|
|
87
91
|
- lib/nitro_intelligence/client/handlers/image_handler.rb
|
|
88
92
|
- lib/nitro_intelligence/client/handlers/observed/audio_transcription_handler.rb
|
|
89
93
|
- lib/nitro_intelligence/client/handlers/observed/chat_handler.rb
|
|
94
|
+
- lib/nitro_intelligence/client/handlers/observed/decision_handler.rb
|
|
90
95
|
- lib/nitro_intelligence/client/handlers/observed/image_handler.rb
|
|
91
96
|
- lib/nitro_intelligence/client/handlers/observed/text_to_speech_handler.rb
|
|
92
97
|
- lib/nitro_intelligence/client/handlers/text_to_speech_handler.rb
|
|
93
98
|
- lib/nitro_intelligence/client/observed.rb
|
|
94
99
|
- lib/nitro_intelligence/client/observers/langfuse_observer.rb
|
|
95
100
|
- lib/nitro_intelligence/configuration.rb
|
|
101
|
+
- lib/nitro_intelligence/decision.rb
|
|
102
|
+
- lib/nitro_intelligence/deprecator.rb
|
|
96
103
|
- lib/nitro_intelligence/langfuse_extension.rb
|
|
97
104
|
- lib/nitro_intelligence/langfuse_tracer_provider.rb
|
|
98
105
|
- lib/nitro_intelligence/media/audio.rb
|
|
@@ -110,7 +117,11 @@ files:
|
|
|
110
117
|
- lib/nitro_intelligence/observability/prompt_resolver.rb
|
|
111
118
|
- lib/nitro_intelligence/observability/prompt_store.rb
|
|
112
119
|
- lib/nitro_intelligence/observability/upload_handler.rb
|
|
120
|
+
- lib/nitro_intelligence/pending_review.rb
|
|
121
|
+
- lib/nitro_intelligence/railtie.rb
|
|
113
122
|
- lib/nitro_intelligence/reporter.rb
|
|
123
|
+
- lib/nitro_intelligence/review_decision.rb
|
|
124
|
+
- lib/nitro_intelligence/run_result.rb
|
|
114
125
|
- lib/nitro_intelligence/tool_call_review_interrupt.rb
|
|
115
126
|
- lib/nitro_intelligence/tool_call_review_validator.rb
|
|
116
127
|
- lib/nitro_intelligence/trace.rb
|