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
|
@@ -7,26 +7,43 @@ module NitroIntelligence
|
|
|
7
7
|
# Credentials are supplied by the host. Where they come from is the host's business -- an
|
|
8
8
|
# environment variable its deployment mounts, a secrets store, a literal in configuration --
|
|
9
9
|
# so nothing here encodes one deployment's wiring.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# assistant = NitroIntelligence.assistants["candidate-concierge"]
|
|
13
|
+
# result = assistant.run(thread_id:, messages:)
|
|
10
14
|
class Assistant
|
|
15
|
+
# Raised when an assistant's entry lacks its `api_key` or `assistant_id`, naming each one
|
|
16
|
+
# missing.
|
|
11
17
|
class ConfigurationError < StandardError; end
|
|
12
18
|
|
|
19
|
+
# @api private
|
|
13
20
|
DEFAULT_USER_ID = Assistants::DEFAULT_USER_ID
|
|
14
21
|
|
|
22
|
+
# @api private
|
|
15
23
|
# `base_url` is not among them: the client defaults it, so it cannot be missing.
|
|
16
24
|
REQUIRED = %w[api_key assistant_id].freeze
|
|
17
25
|
|
|
18
26
|
# The key an assistant is filed and looked up under. Not its name: an entry usually carries
|
|
19
27
|
# a `name` of its own, a human-readable label for the assistant's record, and the two are
|
|
20
28
|
# different things.
|
|
29
|
+
#
|
|
30
|
+
# @return [String]
|
|
21
31
|
attr_reader :key
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
# @return [String] the assistant's id in Assistants
|
|
34
|
+
attr_reader :assistant_id
|
|
35
|
+
# @return [String] the Assistants deployment that serves it
|
|
36
|
+
attr_reader :base_url
|
|
37
|
+
# @return [String] the user its threads are created for
|
|
38
|
+
attr_reader :user_id
|
|
24
39
|
|
|
25
40
|
# The key is positional so that splatting an entry cannot overwrite it, whatever the entry
|
|
26
41
|
# happens to carry.
|
|
27
42
|
#
|
|
28
43
|
# Extra keys are accepted and ignored for the same reason: an entry carries fields the
|
|
29
44
|
# application has no use for, such as the graph or the observability project it reports to.
|
|
45
|
+
#
|
|
46
|
+
# @api private
|
|
30
47
|
def initialize(key, base_url: nil, api_key: nil, assistant_id: nil, user_id: nil, **_kwargs)
|
|
31
48
|
@key = key.to_s
|
|
32
49
|
@base_url = base_url.presence || Assistants::DEFAULT_BASE_URL
|
|
@@ -37,24 +54,86 @@ module NitroIntelligence
|
|
|
37
54
|
validate!
|
|
38
55
|
end
|
|
39
56
|
|
|
57
|
+
# The client the assistant's calls go through, for anything this class does not expose.
|
|
58
|
+
#
|
|
59
|
+
# @return [Assistants]
|
|
40
60
|
def client
|
|
41
61
|
@client ||= Assistants.new(base_url: @base_url, api_key: @api_key, user_id: @user_id)
|
|
42
62
|
end
|
|
43
63
|
|
|
44
|
-
# The
|
|
64
|
+
# The calls that identify an assistant take it from here rather than from the caller.
|
|
45
65
|
# Everything else is thread-scoped and delegates untouched.
|
|
66
|
+
#
|
|
67
|
+
# {Assistants#run} for this assistant.
|
|
68
|
+
#
|
|
69
|
+
# @param thread_id [String]
|
|
70
|
+
# @param messages [Array<Hash>]
|
|
71
|
+
# @param kwargs [Hash] the rest of {Assistants#run}'s arguments, except `assistant_id`
|
|
72
|
+
# @return [RunResult]
|
|
73
|
+
# @raise [ArgumentError] when given an `assistant_id`
|
|
74
|
+
# @raise (see Assistants#run)
|
|
75
|
+
def run(thread_id:, messages:, **kwargs)
|
|
76
|
+
reject_assistant_id!(kwargs)
|
|
77
|
+
client.run(thread_id:, assistant_id:, messages:, **kwargs)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# {Assistants#await_run} for this assistant.
|
|
81
|
+
#
|
|
82
|
+
# @deprecated Use {#run}`(...).reply`. Removed in 5.0.
|
|
83
|
+
# @param (see #run)
|
|
84
|
+
# @return [String, nil]
|
|
85
|
+
# @raise (see #run)
|
|
46
86
|
def await_run(thread_id:, messages:, **kwargs)
|
|
47
87
|
reject_assistant_id!(kwargs)
|
|
48
88
|
client.await_run(thread_id:, assistant_id:, messages:, **kwargs)
|
|
49
89
|
end
|
|
50
90
|
|
|
91
|
+
# {Assistants#review} for this assistant.
|
|
92
|
+
#
|
|
93
|
+
# @param thread_id [String]
|
|
94
|
+
# @param kwargs [Hash] the rest of {Assistants#review}'s arguments, except `assistant_id`
|
|
95
|
+
# @return [RunResult]
|
|
96
|
+
# @raise [ArgumentError] when given an `assistant_id`
|
|
97
|
+
# @raise (see Assistants#review)
|
|
98
|
+
def review(thread_id:, **kwargs)
|
|
99
|
+
reject_assistant_id!(kwargs)
|
|
100
|
+
client.review(thread_id:, assistant_id:, **kwargs)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# {Assistants#review_tool_calls} for this assistant.
|
|
104
|
+
#
|
|
105
|
+
# @deprecated Use {#review}`(tool_calls:, reviewer_id:, interrupt_id:)`. Removed in 5.0.
|
|
106
|
+
# @param thread_id [String]
|
|
107
|
+
# @param tool_calls [Hash, Array<Hash>]
|
|
108
|
+
# @param kwargs [Hash] the rest of {Assistants#review_tool_calls}'s arguments, except
|
|
109
|
+
# `assistant_id`
|
|
110
|
+
# @return [nil]
|
|
111
|
+
# @raise [ArgumentError] when given an `assistant_id`
|
|
112
|
+
# @raise (see Assistants#review_tool_calls)
|
|
51
113
|
def review_tool_calls(thread_id:, tool_calls:, **kwargs)
|
|
52
114
|
reject_assistant_id!(kwargs)
|
|
53
115
|
client.review_tool_calls(thread_id:, assistant_id:, tool_calls:, **kwargs)
|
|
54
116
|
end
|
|
55
117
|
|
|
118
|
+
# @!method thread_state(thread_id:)
|
|
119
|
+
# {Assistants#thread_state}.
|
|
120
|
+
# @return (see Assistants#thread_state)
|
|
121
|
+
# @!method thread_messages(thread_id:)
|
|
122
|
+
# {Assistants#thread_messages}.
|
|
123
|
+
# @return (see Assistants#thread_messages)
|
|
124
|
+
# @!method tool_calls_pending_review(thread_id:)
|
|
125
|
+
# {Assistants#tool_calls_pending_review}.
|
|
126
|
+
# @deprecated (see Assistants#tool_calls_pending_review)
|
|
127
|
+
# @return (see Assistants#tool_calls_pending_review)
|
|
128
|
+
# @!method tool_calls_under_review(thread_id:)
|
|
129
|
+
# {Assistants#tool_calls_under_review}.
|
|
130
|
+
# @deprecated (see Assistants#tool_calls_under_review)
|
|
131
|
+
# @return (see Assistants#tool_calls_under_review)
|
|
132
|
+
# @!method under_review(thread_id:)
|
|
133
|
+
# {Assistants#under_review}.
|
|
134
|
+
# @return (see Assistants#under_review)
|
|
56
135
|
delegate :thread_state, :thread_messages, :tool_calls_pending_review, :tool_calls_under_review,
|
|
57
|
-
to: :client
|
|
136
|
+
:under_review, to: :client
|
|
58
137
|
|
|
59
138
|
private
|
|
60
139
|
|
|
@@ -17,29 +17,47 @@ module NitroIntelligence
|
|
|
17
17
|
# },
|
|
18
18
|
# }
|
|
19
19
|
class AssistantRegistry
|
|
20
|
+
# Raised looking up a key `definitions` does not configure, listing the ones it does.
|
|
20
21
|
class UnknownAssistantError < StandardError; end
|
|
21
22
|
|
|
23
|
+
# @api private
|
|
22
24
|
DEFINITIONS_KEY = "definitions".freeze
|
|
25
|
+
# @api private
|
|
23
26
|
SHARED_KEYS = %w[base_url user_id].freeze
|
|
24
27
|
|
|
28
|
+
# @api private
|
|
25
29
|
def initialize(config = {})
|
|
26
30
|
@config = config.to_h.deep_stringify_keys
|
|
27
31
|
@assistants = {}
|
|
28
32
|
end
|
|
29
33
|
|
|
34
|
+
# The assistant configured under `key`.
|
|
35
|
+
#
|
|
36
|
+
# @param key [String, Symbol]
|
|
37
|
+
# @return [Assistant]
|
|
38
|
+
# @raise [UnknownAssistantError] when `definitions` has no entry for `key`
|
|
39
|
+
# @raise [Assistant::ConfigurationError] when the entry lacks its `api_key` or `assistant_id`
|
|
30
40
|
def [](key)
|
|
31
41
|
fetch(key)
|
|
32
42
|
end
|
|
33
43
|
|
|
44
|
+
# @param (see #[])
|
|
45
|
+
# @return (see #[])
|
|
46
|
+
# @raise (see #[])
|
|
34
47
|
def fetch(key)
|
|
35
48
|
key = key.to_s
|
|
36
49
|
@assistants[key] ||= build(key)
|
|
37
50
|
end
|
|
38
51
|
|
|
52
|
+
# Whether `definitions` has an entry for `key`.
|
|
53
|
+
#
|
|
54
|
+
# @param key [String, Symbol]
|
|
55
|
+
# @return [Boolean]
|
|
39
56
|
def key?(key)
|
|
40
57
|
definitions.key?(key.to_s)
|
|
41
58
|
end
|
|
42
59
|
|
|
60
|
+
# @return [Array<String>] the keys `definitions` configures
|
|
43
61
|
def keys
|
|
44
62
|
definitions.keys
|
|
45
63
|
end
|