riffer 0.31.0 → 0.32.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/.agents/code-style.md +63 -4
- data/.agents/rbs-inline.md +1 -6
- data/.release-please-manifest.json +1 -1
- data/AGENTS.md +1 -2
- data/CHANGELOG.md +25 -0
- data/docs/08_MESSAGES.md +1 -1
- data/docs/13_SKILLS.md +6 -2
- data/docs/14_MCP.md +50 -5
- data/docs/providers/02_AMAZON_BEDROCK.md +14 -0
- data/lib/riffer/agent/config.rb +42 -47
- data/lib/riffer/agent/context.rb +70 -50
- data/lib/riffer/agent/response.rb +4 -20
- data/lib/riffer/agent/run.rb +28 -67
- data/lib/riffer/agent/serializer.rb +22 -81
- data/lib/riffer/agent/session/repair.rb +14 -40
- data/lib/riffer/agent/session.rb +25 -67
- data/lib/riffer/agent/structured_output/result.rb +3 -11
- data/lib/riffer/agent/structured_output.rb +5 -13
- data/lib/riffer/agent.rb +78 -196
- data/lib/riffer/config.rb +34 -101
- data/lib/riffer/evals/evaluator.rb +7 -27
- data/lib/riffer/evals/evaluator_runner.rb +11 -19
- data/lib/riffer/evals/judge.rb +4 -25
- data/lib/riffer/evals/result.rb +1 -18
- data/lib/riffer/evals/run_result.rb +0 -11
- data/lib/riffer/evals/scenario_result.rb +0 -14
- data/lib/riffer/evals.rb +0 -6
- data/lib/riffer/guardrail.rb +4 -27
- data/lib/riffer/guardrails/modification.rb +0 -10
- data/lib/riffer/guardrails/result.rb +3 -30
- data/lib/riffer/guardrails/runner.rb +5 -22
- data/lib/riffer/guardrails/tripwire.rb +1 -19
- data/lib/riffer/guardrails.rb +2 -4
- data/lib/riffer/helpers/call_or_value.rb +4 -3
- data/lib/riffer/helpers/class_name_converter.rb +3 -1
- data/lib/riffer/helpers/dependencies.rb +5 -7
- data/lib/riffer/helpers.rb +0 -5
- data/lib/riffer/mcp/authenticated_tool.rb +9 -9
- data/lib/riffer/mcp/client.rb +12 -17
- data/lib/riffer/mcp/manifest.rb +13 -10
- data/lib/riffer/mcp/registration.rb +2 -11
- data/lib/riffer/mcp/registry.rb +44 -52
- data/lib/riffer/mcp/search_tool.rb +53 -0
- data/lib/riffer/mcp/tool_factory.rb +13 -18
- data/lib/riffer/mcp.rb +12 -17
- data/lib/riffer/messages/assistant.rb +2 -9
- data/lib/riffer/messages/base.rb +46 -16
- data/lib/riffer/messages/file_part.rb +32 -24
- data/lib/riffer/messages/system.rb +0 -5
- data/lib/riffer/messages/tool.rb +0 -10
- data/lib/riffer/messages/user.rb +0 -10
- data/lib/riffer/messages.rb +0 -7
- data/lib/riffer/params/boolean.rb +2 -4
- data/lib/riffer/params/param.rb +28 -39
- data/lib/riffer/params.rb +9 -21
- data/lib/riffer/providers/amazon_bedrock.rb +42 -28
- data/lib/riffer/providers/anthropic.rb +4 -9
- data/lib/riffer/providers/azure_open_ai.rb +3 -19
- data/lib/riffer/providers/base.rb +13 -26
- data/lib/riffer/providers/gemini.rb +4 -4
- data/lib/riffer/providers/mock.rb +6 -26
- data/lib/riffer/providers/open_ai.rb +6 -8
- data/lib/riffer/providers/open_router.rb +4 -10
- data/lib/riffer/providers/repository.rb +4 -3
- data/lib/riffer/providers/token_usage.rb +9 -20
- data/lib/riffer/providers.rb +0 -8
- data/lib/riffer/runner/fibers.rb +10 -16
- data/lib/riffer/runner/sequential.rb +1 -4
- data/lib/riffer/runner/threaded.rb +3 -14
- data/lib/riffer/runner.rb +2 -15
- data/lib/riffer/skills/activate_tool.rb +3 -11
- data/lib/riffer/skills/adapter.rb +4 -22
- data/lib/riffer/skills/backend.rb +7 -21
- data/lib/riffer/skills/config.rb +10 -31
- data/lib/riffer/skills/context.rb +21 -21
- data/lib/riffer/skills/filesystem_backend.rb +7 -25
- data/lib/riffer/skills/frontmatter.rb +22 -32
- data/lib/riffer/skills/markdown_adapter.rb +2 -9
- data/lib/riffer/skills/xml_adapter.rb +2 -8
- data/lib/riffer/stream_events/base.rb +1 -6
- data/lib/riffer/stream_events/guardrail_modification.rb +1 -8
- data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -8
- data/lib/riffer/stream_events/interrupt.rb +4 -7
- data/lib/riffer/stream_events/reasoning_delta.rb +2 -4
- data/lib/riffer/stream_events/reasoning_done.rb +2 -4
- data/lib/riffer/stream_events/skill_activation.rb +2 -4
- data/lib/riffer/stream_events/text_delta.rb +0 -2
- data/lib/riffer/stream_events/text_done.rb +1 -3
- data/lib/riffer/stream_events/token_usage_done.rb +1 -8
- data/lib/riffer/stream_events/tool_call_delta.rb +2 -3
- data/lib/riffer/stream_events/tool_call_done.rb +1 -3
- data/lib/riffer/stream_events/web_search_done.rb +1 -3
- data/lib/riffer/stream_events/web_search_status.rb +2 -3
- data/lib/riffer/stream_events.rb +0 -10
- data/lib/riffer/tool.rb +6 -13
- data/lib/riffer/tools/response.rb +8 -4
- data/lib/riffer/tools/runtime/fibers.rb +0 -3
- data/lib/riffer/tools/runtime/inline.rb +1 -4
- data/lib/riffer/tools/runtime/threaded.rb +0 -2
- data/lib/riffer/tools/runtime.rb +5 -38
- data/lib/riffer/tools/toolable.rb +5 -16
- data/lib/riffer/tools.rb +0 -4
- data/lib/riffer/version.rb +1 -1
- data/lib/riffer.rb +7 -8
- data/sig/generated/riffer/agent/config.rbs +29 -46
- data/sig/generated/riffer/agent/context.rbs +40 -48
- data/sig/generated/riffer/agent/response.rbs +4 -20
- data/sig/generated/riffer/agent/run.rbs +12 -61
- data/sig/generated/riffer/agent/serializer.rbs +21 -80
- data/sig/generated/riffer/agent/session/repair.rbs +12 -40
- data/sig/generated/riffer/agent/session.rbs +25 -67
- data/sig/generated/riffer/agent/structured_output/result.rbs +2 -10
- data/sig/generated/riffer/agent/structured_output.rbs +5 -12
- data/sig/generated/riffer/agent.rbs +57 -186
- data/sig/generated/riffer/config.rbs +34 -100
- data/sig/generated/riffer/evals/evaluator.rbs +7 -27
- data/sig/generated/riffer/evals/evaluator_runner.rbs +9 -19
- data/sig/generated/riffer/evals/judge.rbs +4 -24
- data/sig/generated/riffer/evals/result.rbs +1 -17
- data/sig/generated/riffer/evals/run_result.rbs +0 -10
- data/sig/generated/riffer/evals/scenario_result.rbs +0 -13
- data/sig/generated/riffer/evals.rbs +0 -6
- data/sig/generated/riffer/guardrail.rbs +4 -27
- data/sig/generated/riffer/guardrails/modification.rbs +0 -10
- data/sig/generated/riffer/guardrails/result.rbs +3 -30
- data/sig/generated/riffer/guardrails/runner.rbs +5 -22
- data/sig/generated/riffer/guardrails/tripwire.rbs +1 -19
- data/sig/generated/riffer/guardrails.rbs +2 -4
- data/sig/generated/riffer/helpers/call_or_value.rbs +4 -3
- data/sig/generated/riffer/helpers/class_name_converter.rbs +1 -1
- data/sig/generated/riffer/helpers/dependencies.rbs +3 -7
- data/sig/generated/riffer/helpers.rbs +0 -5
- data/sig/generated/riffer/mcp/authenticated_tool.rbs +5 -4
- data/sig/generated/riffer/mcp/client.rbs +10 -16
- data/sig/generated/riffer/mcp/manifest.rbs +9 -9
- data/sig/generated/riffer/mcp/registration.rbs +2 -10
- data/sig/generated/riffer/mcp/registry.rbs +11 -18
- data/sig/generated/riffer/mcp/search_tool.rbs +26 -0
- data/sig/generated/riffer/mcp/tool_factory.rbs +10 -15
- data/sig/generated/riffer/mcp.rbs +10 -17
- data/sig/generated/riffer/messages/assistant.rbs +2 -8
- data/sig/generated/riffer/messages/base.rbs +11 -16
- data/sig/generated/riffer/messages/file_part.rbs +13 -23
- data/sig/generated/riffer/messages/system.rbs +0 -4
- data/sig/generated/riffer/messages/tool.rbs +0 -9
- data/sig/generated/riffer/messages/user.rbs +0 -9
- data/sig/generated/riffer/messages.rbs +0 -7
- data/sig/generated/riffer/params/boolean.rbs +2 -4
- data/sig/generated/riffer/params/param.rbs +21 -39
- data/sig/generated/riffer/params.rbs +9 -21
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +21 -25
- data/sig/generated/riffer/providers/anthropic.rbs +2 -7
- data/sig/generated/riffer/providers/azure_open_ai.rbs +3 -18
- data/sig/generated/riffer/providers/base.rbs +9 -25
- data/sig/generated/riffer/providers/gemini.rbs +0 -2
- data/sig/generated/riffer/providers/mock.rbs +6 -26
- data/sig/generated/riffer/providers/open_ai.rbs +1 -5
- data/sig/generated/riffer/providers/open_router.rbs +4 -10
- data/sig/generated/riffer/providers/repository.rbs +2 -3
- data/sig/generated/riffer/providers/token_usage.rbs +6 -16
- data/sig/generated/riffer/providers.rbs +0 -8
- data/sig/generated/riffer/runner/fibers.rbs +8 -15
- data/sig/generated/riffer/runner/sequential.rbs +1 -3
- data/sig/generated/riffer/runner/threaded.rbs +3 -13
- data/sig/generated/riffer/runner.rbs +2 -14
- data/sig/generated/riffer/skills/activate_tool.rbs +2 -11
- data/sig/generated/riffer/skills/adapter.rbs +4 -22
- data/sig/generated/riffer/skills/backend.rbs +7 -21
- data/sig/generated/riffer/skills/config.rbs +10 -31
- data/sig/generated/riffer/skills/context.rbs +15 -20
- data/sig/generated/riffer/skills/filesystem_backend.rbs +7 -24
- data/sig/generated/riffer/skills/frontmatter.rbs +19 -29
- data/sig/generated/riffer/skills/markdown_adapter.rbs +2 -9
- data/sig/generated/riffer/skills/xml_adapter.rbs +2 -8
- data/sig/generated/riffer/stream_events/base.rbs +1 -6
- data/sig/generated/riffer/stream_events/guardrail_modification.rbs +1 -8
- data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +1 -8
- data/sig/generated/riffer/stream_events/interrupt.rbs +4 -7
- data/sig/generated/riffer/stream_events/reasoning_delta.rbs +2 -4
- data/sig/generated/riffer/stream_events/reasoning_done.rbs +2 -4
- data/sig/generated/riffer/stream_events/skill_activation.rbs +2 -4
- data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
- data/sig/generated/riffer/stream_events/text_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/token_usage_done.rbs +1 -7
- data/sig/generated/riffer/stream_events/tool_call_delta.rbs +2 -3
- data/sig/generated/riffer/stream_events/tool_call_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/web_search_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/web_search_status.rbs +2 -3
- data/sig/generated/riffer/stream_events.rbs +0 -10
- data/sig/generated/riffer/tool.rbs +5 -12
- data/sig/generated/riffer/tools/response.rbs +6 -4
- data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -3
- data/sig/generated/riffer/tools/runtime/inline.rbs +1 -3
- data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -2
- data/sig/generated/riffer/tools/runtime.rbs +5 -37
- data/sig/generated/riffer/tools/toolable.rbs +4 -14
- data/sig/generated/riffer/tools.rbs +0 -4
- data/sig/generated/riffer.rbs +5 -4
- data/sig/manual/riffer/agent/session/repair.rbs +5 -0
- data/sig/manual/riffer/evals/evaluator_runner.rbs +5 -0
- data/sig/manual/riffer/helpers/class_name_converter.rbs +5 -0
- data/sig/manual/riffer/helpers/dependencies.rbs +5 -0
- data/sig/manual/riffer/mcp/authenticated_tool.rbs +5 -0
- data/sig/manual/riffer/mcp/registry.rbs +5 -0
- data/sig/manual/riffer/mcp/tool_factory.rbs +5 -0
- data/sig/manual/riffer/mcp.rbs +5 -0
- data/sig/manual/riffer/providers/repository.rbs +5 -0
- data/sig/manual/riffer.rbs +5 -0
- metadata +17 -9
- data/.agents/rdoc.md +0 -69
- data/lib/riffer/messages/converter.rb +0 -90
- data/sig/generated/riffer/messages/converter.rbs +0 -33
- data/sig/manual/riffer/tools/toolable.rbs +0 -6
data/lib/riffer/messages/base.rb
CHANGED
|
@@ -3,10 +3,49 @@
|
|
|
3
3
|
|
|
4
4
|
require "securerandom"
|
|
5
5
|
|
|
6
|
-
# Base class for all message types
|
|
7
|
-
#
|
|
8
|
-
# Subclasses must implement the +role+ method.
|
|
6
|
+
# Base class for all message types. Subclasses must implement +role+.
|
|
9
7
|
class Riffer::Messages::Base
|
|
8
|
+
# Builds the matching message subclass from a hash, or returns +msg+ unchanged
|
|
9
|
+
# when it is already a message. Raises Riffer::ArgumentError on an invalid message.
|
|
10
|
+
#--
|
|
11
|
+
#: ((Hash[Symbol, untyped] | Riffer::Messages::Base)) -> Riffer::Messages::Base
|
|
12
|
+
def self.from_hash(msg)
|
|
13
|
+
return msg if msg.is_a?(Riffer::Messages::Base)
|
|
14
|
+
|
|
15
|
+
unless msg.is_a?(Hash)
|
|
16
|
+
raise Riffer::ArgumentError, "Message must be a Hash or Message object, got #{msg.class}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
role = msg[:role]
|
|
20
|
+
content = msg[:content]
|
|
21
|
+
|
|
22
|
+
if role.nil? || role.empty?
|
|
23
|
+
raise Riffer::ArgumentError, "Message hash must include a 'role' key"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
id = msg[:id]
|
|
27
|
+
|
|
28
|
+
case role.to_sym
|
|
29
|
+
when :user
|
|
30
|
+
files = (msg[:files] || []).map { |f| Riffer::Messages::FilePart.from_hash(f) }
|
|
31
|
+
Riffer::Messages::User.new(content, id: id, files: files)
|
|
32
|
+
when :assistant
|
|
33
|
+
tool_calls = (msg[:tool_calls] || []).map { |tc|
|
|
34
|
+
tc.is_a?(Riffer::Messages::Assistant::ToolCall) ? tc : Riffer::Messages::Assistant::ToolCall.new(**tc)
|
|
35
|
+
}
|
|
36
|
+
structured_output = msg[:structured_output]
|
|
37
|
+
Riffer::Messages::Assistant.new(content, id: id, tool_calls: tool_calls, structured_output: structured_output)
|
|
38
|
+
when :system
|
|
39
|
+
Riffer::Messages::System.new(content, id: id)
|
|
40
|
+
when :tool
|
|
41
|
+
tool_call_id = msg[:tool_call_id]
|
|
42
|
+
name = msg[:name]
|
|
43
|
+
Riffer::Messages::Tool.new(content, id: id, tool_call_id: tool_call_id, name: name)
|
|
44
|
+
else
|
|
45
|
+
raise Riffer::ArgumentError, "Unknown message role: #{role}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
10
49
|
# The message content.
|
|
11
50
|
attr_reader :content #: String
|
|
12
51
|
|
|
@@ -31,31 +70,22 @@ class Riffer::Messages::Base
|
|
|
31
70
|
end
|
|
32
71
|
|
|
33
72
|
# Returns the message role.
|
|
34
|
-
#
|
|
35
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
36
|
-
#
|
|
37
73
|
#--
|
|
38
74
|
#: () -> Symbol
|
|
39
75
|
def role
|
|
40
76
|
raise NotImplementedError, "Subclasses must implement #role"
|
|
41
77
|
end
|
|
42
78
|
|
|
43
|
-
# Whether this message carries pending tool calls
|
|
44
|
-
# +Riffer::Messages::Assistant+
|
|
45
|
-
# array is non-empty.
|
|
46
|
-
#
|
|
79
|
+
# Whether this message carries pending tool calls (overridden by
|
|
80
|
+
# +Riffer::Messages::Assistant+).
|
|
47
81
|
#--
|
|
48
82
|
#: () -> bool
|
|
49
83
|
def has_tool_calls?
|
|
50
84
|
false
|
|
51
85
|
end
|
|
52
86
|
|
|
53
|
-
# Merges another same-role message into this one.
|
|
54
|
-
#
|
|
55
|
-
# Raises NotImplementedError unless implemented by subclass. Mergeable
|
|
56
|
-
# message types (+User+, +Assistant+, +System+) override this; +Tool+
|
|
57
|
-
# messages are never merged.
|
|
58
|
-
#
|
|
87
|
+
# Merges another same-role message into this one. +Tool+ messages are never
|
|
88
|
+
# merged.
|
|
59
89
|
#--
|
|
60
90
|
#: (untyped) -> Riffer::Messages::Base
|
|
61
91
|
def +(other)
|
|
@@ -4,16 +4,8 @@
|
|
|
4
4
|
require "base64"
|
|
5
5
|
require "uri"
|
|
6
6
|
|
|
7
|
-
# Represents a file attachment (image or document)
|
|
8
|
-
#
|
|
9
|
-
# Supports two input sources:
|
|
10
|
-
# - URLs (stored and passed to providers that support them via +from_url+)
|
|
11
|
-
# - Raw base64 data (via +new+)
|
|
12
|
-
#
|
|
13
|
-
# file = Riffer::Messages::FilePart.from_url("https://example.com/doc.pdf", media_type: "application/pdf")
|
|
14
|
-
# file.url? # => true
|
|
15
|
-
# file.document? # => true
|
|
16
|
-
#
|
|
7
|
+
# Represents a file attachment (image or document) — from a URL (+from_url+) or
|
|
8
|
+
# raw base64 data (+new+).
|
|
17
9
|
class Riffer::Messages::FilePart
|
|
18
10
|
# @rbs @url_string: String?
|
|
19
11
|
|
|
@@ -38,13 +30,8 @@ class Riffer::Messages::FilePart
|
|
|
38
30
|
# The filename, if available.
|
|
39
31
|
attr_reader :filename #: String?
|
|
40
32
|
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# At least one of +data+ or +url+ must be provided.
|
|
44
|
-
#
|
|
45
|
-
# Raises Riffer::ArgumentError if neither data nor url is provided,
|
|
46
|
-
# or if media_type is not supported.
|
|
47
|
-
#
|
|
33
|
+
# Raises Riffer::ArgumentError unless +data+ or +url+ is given and
|
|
34
|
+
# +media_type+ is supported.
|
|
48
35
|
#--
|
|
49
36
|
#: (media_type: String, ?data: String?, ?filename: String?, ?url: String?) -> void
|
|
50
37
|
def initialize(media_type:, data: nil, filename: nil, url: nil)
|
|
@@ -57,13 +44,8 @@ class Riffer::Messages::FilePart
|
|
|
57
44
|
@url_string = url
|
|
58
45
|
end
|
|
59
46
|
|
|
60
|
-
# Creates a FilePart from a URL
|
|
61
|
-
#
|
|
62
|
-
# The URL is stored and passed directly to providers that support URL sources.
|
|
63
|
-
# If +media_type+ is not provided, it is detected from the URL path extension.
|
|
64
|
-
#
|
|
65
|
-
# Raises Riffer::ArgumentError if media_type cannot be detected.
|
|
66
|
-
#
|
|
47
|
+
# Creates a FilePart from a URL, detecting +media_type+ from the path
|
|
48
|
+
# extension when omitted. Raises Riffer::ArgumentError if it can't be detected.
|
|
67
49
|
#--
|
|
68
50
|
#: (String, ?media_type: String?) -> Riffer::Messages::FilePart
|
|
69
51
|
def self.from_url(url, media_type: nil)
|
|
@@ -76,6 +58,32 @@ class Riffer::Messages::FilePart
|
|
|
76
58
|
new(url: url, media_type: media_type)
|
|
77
59
|
end
|
|
78
60
|
|
|
61
|
+
# Builds a FilePart from a +{url:, media_type:}+ or +{data:, media_type:}+ hash,
|
|
62
|
+
# or returns +file+ unchanged when it is already a FilePart. Raises
|
|
63
|
+
# Riffer::ArgumentError on an invalid hash.
|
|
64
|
+
#--
|
|
65
|
+
#: ((Hash[Symbol, untyped] | Riffer::Messages::FilePart)) -> Riffer::Messages::FilePart
|
|
66
|
+
def self.from_hash(file)
|
|
67
|
+
return file if file.is_a?(Riffer::Messages::FilePart)
|
|
68
|
+
|
|
69
|
+
unless file.is_a?(Hash)
|
|
70
|
+
raise Riffer::ArgumentError, "File must be a Hash or FilePart object, got #{file.class}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
url = file[:url]
|
|
74
|
+
data = file[:data]
|
|
75
|
+
media_type = file[:media_type]
|
|
76
|
+
filename = file[:filename]
|
|
77
|
+
|
|
78
|
+
if url
|
|
79
|
+
from_url(url, media_type: media_type)
|
|
80
|
+
elsif data && media_type
|
|
81
|
+
new(data: data, media_type: media_type, filename: filename)
|
|
82
|
+
else
|
|
83
|
+
raise Riffer::ArgumentError, "File hash must include :url or :data with :media_type"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
79
87
|
# Returns the base64-encoded data, or nil for URL-only sources.
|
|
80
88
|
attr_reader :data #: String?
|
|
81
89
|
|
|
@@ -2,11 +2,6 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Represents a system message (instructions) in a conversation.
|
|
5
|
-
#
|
|
6
|
-
# msg = Riffer::Messages::System.new("You are a helpful assistant.")
|
|
7
|
-
# msg.role # => :system
|
|
8
|
-
# msg.content # => "You are a helpful assistant."
|
|
9
|
-
#
|
|
10
5
|
class Riffer::Messages::System < Riffer::Messages::Base
|
|
11
6
|
#--
|
|
12
7
|
#: () -> Symbol
|
data/lib/riffer/messages/tool.rb
CHANGED
|
@@ -2,16 +2,6 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Represents a tool execution result in a conversation.
|
|
5
|
-
#
|
|
6
|
-
# msg = Riffer::Messages::Tool.new(
|
|
7
|
-
# "The weather is sunny.",
|
|
8
|
-
# tool_call_id: "call_123",
|
|
9
|
-
# name: "weather_tool"
|
|
10
|
-
# )
|
|
11
|
-
# msg.role # => :tool
|
|
12
|
-
# msg.tool_call_id # => "call_123"
|
|
13
|
-
# msg.error? # => false
|
|
14
|
-
#
|
|
15
5
|
class Riffer::Messages::Tool < Riffer::Messages::Base
|
|
16
6
|
# The ID of the tool call this result responds to.
|
|
17
7
|
attr_reader :tool_call_id #: String
|
data/lib/riffer/messages/user.rb
CHANGED
|
@@ -2,20 +2,10 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Represents a user message in a conversation.
|
|
5
|
-
#
|
|
6
|
-
# msg = Riffer::Messages::User.new("Hello!")
|
|
7
|
-
# msg.role # => :user
|
|
8
|
-
# msg.content # => "Hello!"
|
|
9
|
-
#
|
|
10
|
-
# msg = Riffer::Messages::User.new("Describe this image", files: [file_part])
|
|
11
|
-
# msg.files # => [#<Riffer::Messages::FilePart ...>]
|
|
12
|
-
#
|
|
13
5
|
class Riffer::Messages::User < Riffer::Messages::Base
|
|
14
6
|
# File attachments for this message.
|
|
15
7
|
attr_reader :files #: Array[Riffer::Messages::FilePart]
|
|
16
8
|
|
|
17
|
-
# Initializes a user message.
|
|
18
|
-
#
|
|
19
9
|
#--
|
|
20
10
|
#: (String, ?id: String?, ?files: Array[Riffer::Messages::FilePart]) -> void
|
|
21
11
|
def initialize(content, id: nil, files: [])
|
data/lib/riffer/messages.rb
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Namespace for message types in the Riffer framework.
|
|
5
|
-
#
|
|
6
|
-
# Message objects represent the conversation between users and the assistant:
|
|
7
|
-
# - Riffer::Messages::System - System instructions
|
|
8
|
-
# - Riffer::Messages::User - User input
|
|
9
|
-
# - Riffer::Messages::Assistant - LLM responses
|
|
10
|
-
# - Riffer::Messages::Tool - Tool execution results
|
|
11
4
|
module Riffer::Messages
|
|
12
5
|
end
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Ruby has no +Boolean+ class (+true+ is +TrueClass+, +false+ is +FalseClass+).
|
|
7
|
-
# Use this module wherever you need a single type that means "boolean":
|
|
4
|
+
# Sentinel type for declaring boolean parameters — Ruby has no +Boolean+ class
|
|
5
|
+
# (+true+/+false+ are +TrueClass+/+FalseClass+).
|
|
8
6
|
#
|
|
9
7
|
# required :verbose, Riffer::Params::Boolean
|
|
10
8
|
#
|
data/lib/riffer/params/param.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Handles type validation and JSON Schema generation for individual parameters.
|
|
4
|
+
# A single parameter definition, handling type validation and JSON Schema
|
|
5
|
+
# generation.
|
|
7
6
|
class Riffer::Params::Param
|
|
8
7
|
# Maps Ruby types to JSON Schema type strings
|
|
9
8
|
TYPE_MAPPINGS = {
|
|
@@ -20,9 +19,8 @@ class Riffer::Params::Param
|
|
|
20
19
|
# Primitive types allowed for the <tt>of:</tt> keyword on Array params
|
|
21
20
|
PRIMITIVE_TYPES = (TYPE_MAPPINGS.keys - [Array, Hash]).freeze #: Array[Module]
|
|
22
21
|
|
|
23
|
-
# Maps JSON Schema type strings back to Ruby types
|
|
24
|
-
#
|
|
25
|
-
# Riffer::Params::Boolean. Used by +from_json_schema+.
|
|
22
|
+
# Maps JSON Schema type strings back to Ruby types (inverse of TYPE_MAPPINGS),
|
|
23
|
+
# collapsing the three boolean spellings onto Riffer::Params::Boolean.
|
|
26
24
|
JSON_TYPE_MAPPINGS = {
|
|
27
25
|
"string" => String,
|
|
28
26
|
"integer" => Integer,
|
|
@@ -32,24 +30,32 @@ class Riffer::Params::Param
|
|
|
32
30
|
"object" => Hash
|
|
33
31
|
}.freeze #: Hash[String, Module]
|
|
34
32
|
|
|
33
|
+
# The parameter name.
|
|
35
34
|
attr_reader :name #: Symbol
|
|
35
|
+
|
|
36
|
+
# The Ruby type.
|
|
36
37
|
attr_reader :type #: Module
|
|
38
|
+
|
|
39
|
+
# Whether the parameter is required.
|
|
37
40
|
attr_reader :required #: bool
|
|
41
|
+
|
|
42
|
+
# The parameter description, if any.
|
|
38
43
|
attr_reader :description #: String?
|
|
44
|
+
|
|
45
|
+
# Allowed values, if constrained.
|
|
39
46
|
attr_reader :enum #: Array[untyped]?
|
|
47
|
+
|
|
48
|
+
# The default value, if any.
|
|
40
49
|
attr_reader :default #: untyped
|
|
50
|
+
|
|
51
|
+
# Element type for a typed array (+of:+).
|
|
41
52
|
attr_reader :item_type #: Module?
|
|
53
|
+
|
|
54
|
+
# Nested Params for object / array-of-object types.
|
|
42
55
|
attr_reader :nested_params #: Riffer::Params?
|
|
43
56
|
|
|
44
|
-
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
# [name] the parameter name (Symbol).
|
|
48
|
-
# [schema] the property's JSON Schema (Symbol-keyed).
|
|
49
|
-
# [required] whether the property appeared in the parent's +required+ list.
|
|
50
|
-
#
|
|
51
|
-
# Raises Riffer::ArgumentError on a type outside the Params-expressible subset.
|
|
52
|
-
#
|
|
57
|
+
# Reconstructs a Param from a single JSON Schema property. Raises
|
|
58
|
+
# Riffer::ArgumentError on a type outside the Params-expressible subset.
|
|
53
59
|
#--
|
|
54
60
|
#: (Symbol, Hash[Symbol, untyped], required: bool) -> Riffer::Params::Param
|
|
55
61
|
def self.from_json_schema(name, schema, required:)
|
|
@@ -68,10 +74,6 @@ class Riffer::Params::Param
|
|
|
68
74
|
)
|
|
69
75
|
end
|
|
70
76
|
|
|
71
|
-
# Resolves the +[item_type, nested_params]+ pair for a reconstructed Param:
|
|
72
|
-
# a nested Params for object / array-of-object schemas, an +item_type+ for
|
|
73
|
-
# typed primitive arrays, and +nil+ for everything else.
|
|
74
|
-
#
|
|
75
77
|
#--
|
|
76
78
|
#: (Module, Hash[Symbol, untyped]) -> [Module?, Riffer::Params?]
|
|
77
79
|
def self.resolve_nesting(ruby_type, schema)
|
|
@@ -86,12 +88,9 @@ class Riffer::Params::Param
|
|
|
86
88
|
end
|
|
87
89
|
private_class_method :resolve_nesting
|
|
88
90
|
|
|
89
|
-
# Resolves a JSON Schema +type+ (
|
|
90
|
-
#
|
|
91
|
-
# Riffer::
|
|
92
|
-
# +type+ attribute uses. Raises Riffer::ArgumentError on a type outside the
|
|
93
|
-
# Params-expressible subset (the block runs only for an unmapped type).
|
|
94
|
-
#
|
|
91
|
+
# Resolves a JSON Schema +type+ (or a <tt>[type, "null"]</tt> union) to its
|
|
92
|
+
# Ruby type. Returns a Module — Riffer::Params::Boolean is a Module, not a
|
|
93
|
+
# Class. Raises Riffer::ArgumentError on an unsupported type.
|
|
95
94
|
#--
|
|
96
95
|
#: (untyped) -> Module
|
|
97
96
|
def self.json_type_to_ruby(type)
|
|
@@ -135,21 +134,11 @@ class Riffer::Params::Param
|
|
|
135
134
|
TYPE_MAPPINGS[type] || type.to_s.downcase
|
|
136
135
|
end
|
|
137
136
|
|
|
138
|
-
# Converts this parameter to JSON Schema format.
|
|
139
|
-
#
|
|
140
|
-
#
|
|
141
|
-
#
|
|
142
|
-
# "absent" from "present" without rejecting the schema.
|
|
143
|
-
#
|
|
144
|
-
# Optional parameters with an +enum+ use +anyOf+ to separate the enum
|
|
145
|
-
# constraint from the null type, since providers like Anthropic reject
|
|
137
|
+
# Converts this parameter to JSON Schema format. When +strict+, optional
|
|
138
|
+
# params are made nullable (<tt>["type", "null"]</tt>) so strict providers
|
|
139
|
+
# distinguish absent from present; optional params with an +enum+ use +anyOf+
|
|
140
|
+
# instead, since providers like Anthropic reject
|
|
146
141
|
# <tt>{"type": ["string", "null"], "enum": [...]}</tt>.
|
|
147
|
-
#
|
|
148
|
-
# In non-strict mode a +default+ is emitted when set (a standard JSON
|
|
149
|
-
# Schema keyword), making the schema a lossless source for
|
|
150
|
-
# +Riffer::Params.from_json_schema+. Strict mode omits it, since strict
|
|
151
|
-
# providers reject the keyword.
|
|
152
|
-
#
|
|
153
142
|
#--
|
|
154
143
|
#: (?strict: bool) -> Hash[Symbol, untyped]
|
|
155
144
|
def to_json_schema(strict: false)
|
data/lib/riffer/params.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Used within a Tool's +params+ block to define required and optional parameters,
|
|
7
|
-
# and by StructuredOutput to define response schemas.
|
|
4
|
+
# A DSL for defining tool parameters and structured-output schemas, used within
|
|
5
|
+
# a Tool's +params+ block.
|
|
8
6
|
#
|
|
9
7
|
# params do
|
|
10
8
|
# required :city, String, description: "The city name"
|
|
@@ -12,6 +10,7 @@
|
|
|
12
10
|
# end
|
|
13
11
|
#
|
|
14
12
|
class Riffer::Params
|
|
13
|
+
# The defined parameters.
|
|
15
14
|
attr_reader :parameters #: Array[Riffer::Params::Param]
|
|
16
15
|
|
|
17
16
|
#--
|
|
@@ -20,17 +19,9 @@ class Riffer::Params
|
|
|
20
19
|
@parameters = []
|
|
21
20
|
end
|
|
22
21
|
|
|
23
|
-
# Reconstructs a Params from a JSON Schema object
|
|
24
|
-
# +to_json_schema(strict: false)
|
|
25
|
-
#
|
|
26
|
-
# Accepts the Symbol-keyed object schema produced by +to_json_schema+
|
|
27
|
-
# (property-name keys may be String or Symbol — both are normalized).
|
|
28
|
-
# Reconstructs types, +required+, +description+, +enum+, +default+,
|
|
29
|
-
# typed-array +item_type+, and nested object/array Params recursively.
|
|
30
|
-
#
|
|
31
|
-
# Round-trips losslessly with +to_json_schema(strict: false)+ over the
|
|
32
|
-
# Params-expressible subset of JSON Schema. Raises Riffer::ArgumentError
|
|
33
|
-
# on a schema using features outside that subset.
|
|
22
|
+
# Reconstructs a Params from a JSON Schema object — the inverse of
|
|
23
|
+
# +to_json_schema(strict: false)+. Raises Riffer::ArgumentError on features
|
|
24
|
+
# outside the Params-expressible subset of JSON Schema.
|
|
34
25
|
#
|
|
35
26
|
# schema = params.to_json_schema(strict: false)
|
|
36
27
|
# Riffer::Params.from_json_schema(schema) # => equivalent Riffer::Params
|
|
@@ -129,12 +120,9 @@ class Riffer::Params
|
|
|
129
120
|
validated
|
|
130
121
|
end
|
|
131
122
|
|
|
132
|
-
# Converts all parameters to JSON Schema format.
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
# optional properties are made nullable instead. This satisfies
|
|
136
|
-
# providers that enforce strict structured output schemas.
|
|
137
|
-
#
|
|
123
|
+
# Converts all parameters to JSON Schema format. When +strict+ is true, every
|
|
124
|
+
# property is listed in +required+ and optional ones are made nullable
|
|
125
|
+
# instead, satisfying providers that enforce strict structured output schemas.
|
|
138
126
|
#--
|
|
139
127
|
#: (?strict: bool) -> Hash[Symbol, untyped]
|
|
140
128
|
def to_json_schema(strict: false)
|
|
@@ -3,23 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
require "base64"
|
|
5
5
|
|
|
6
|
-
# Amazon Bedrock provider for Claude and other foundation models.
|
|
7
|
-
#
|
|
8
|
-
# Requires the +aws-sdk-bedrockruntime+ gem to be installed.
|
|
9
|
-
#
|
|
10
|
-
# See https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/BedrockRuntime/Client.html
|
|
6
|
+
# Amazon Bedrock provider for Claude and other foundation models. Requires the
|
|
7
|
+
# +aws-sdk-bedrockruntime+ gem.
|
|
11
8
|
class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
12
|
-
# Matches Anthropic models on Bedrock
|
|
13
|
-
# +anthropic.claude
|
|
14
|
-
# ids like +us.anthropic.claude-sonnet-4-6+.
|
|
9
|
+
# Matches Anthropic models on Bedrock — bare (+anthropic.claude-...+) and
|
|
10
|
+
# cross-region (+us.anthropic.claude-...+) ids.
|
|
15
11
|
ANTHROPIC_MODEL_PATTERN = /(?:^|\.)anthropic\./ #: Regexp
|
|
16
12
|
|
|
17
|
-
# Returns the
|
|
18
|
-
#
|
|
19
|
-
# Bedrock hosts models from multiple vendors. Anthropic models prefer
|
|
20
|
-
# XML-rendered catalogs; everything else falls back to the default
|
|
21
|
-
# Markdown adapter.
|
|
22
|
-
#
|
|
13
|
+
# Returns the skill adapter for the Bedrock model — XML for Anthropic models
|
|
14
|
+
# (which Bedrock hosts alongside other vendors'), else Markdown.
|
|
23
15
|
#--
|
|
24
16
|
#: (?String?) -> singleton(Riffer::Skills::Adapter)
|
|
25
17
|
def self.skills_adapter(model = nil)
|
|
@@ -27,8 +19,6 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
|
27
19
|
Riffer::Skills::MarkdownAdapter
|
|
28
20
|
end
|
|
29
21
|
|
|
30
|
-
# Initializes the Amazon Bedrock provider.
|
|
31
|
-
#
|
|
32
22
|
#--
|
|
33
23
|
#: (?api_token: String?, ?region: String?, **untyped) -> void
|
|
34
24
|
def initialize(api_token: nil, region: nil, **options)
|
|
@@ -57,12 +47,13 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
|
57
47
|
partitioned_messages = partition_messages(messages)
|
|
58
48
|
tools = options[:tools]
|
|
59
49
|
structured_output = options[:structured_output]
|
|
50
|
+
cache_control = options[:cache_control]
|
|
60
51
|
|
|
61
52
|
params = {
|
|
62
53
|
model_id: model,
|
|
63
54
|
system: partitioned_messages[:system],
|
|
64
55
|
messages: partitioned_messages[:conversation],
|
|
65
|
-
**options.except(:tools, :structured_output)
|
|
56
|
+
**options.except(:tools, :structured_output, :cache_control)
|
|
66
57
|
} #: Hash[Symbol, untyped]
|
|
67
58
|
|
|
68
59
|
if tools && !tools.empty?
|
|
@@ -88,9 +79,37 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
|
88
79
|
}
|
|
89
80
|
end
|
|
90
81
|
|
|
82
|
+
apply_cache_point(params, cache_control) if cache_control
|
|
83
|
+
|
|
91
84
|
params
|
|
92
85
|
end
|
|
93
86
|
|
|
87
|
+
# Converse chains +tools -> system -> messages+, so a single +cachePoint+ at
|
|
88
|
+
# the end of the system array (or the tools array, when there is no system
|
|
89
|
+
# prompt) also caches the preceding sections.
|
|
90
|
+
#--
|
|
91
|
+
#: (Hash[Symbol, untyped], untyped) -> void
|
|
92
|
+
def apply_cache_point(params, cache_control)
|
|
93
|
+
cache_point = {cache_point: build_cache_point(cache_control)}
|
|
94
|
+
system = params[:system]
|
|
95
|
+
tools = params.dig(:tool_config, :tools)
|
|
96
|
+
|
|
97
|
+
if system && !system.empty?
|
|
98
|
+
system << cache_point
|
|
99
|
+
elsif tools && !tools.empty?
|
|
100
|
+
tools << cache_point
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
#--
|
|
105
|
+
#: (untyped) -> Hash[Symbol, untyped]
|
|
106
|
+
def build_cache_point(cache_control)
|
|
107
|
+
point = {type: "default"} #: Hash[Symbol, untyped]
|
|
108
|
+
ttl = cache_control.is_a?(Hash) ? cache_control[:ttl] : nil
|
|
109
|
+
point[:ttl] = ttl if ttl
|
|
110
|
+
point
|
|
111
|
+
end
|
|
112
|
+
|
|
94
113
|
#--
|
|
95
114
|
#: (Hash[Symbol, untyped]) -> untyped
|
|
96
115
|
def execute_generate(params)
|
|
@@ -106,7 +125,7 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
|
106
125
|
Riffer::Providers::TokenUsage.new(
|
|
107
126
|
input_tokens: usage.input_tokens,
|
|
108
127
|
output_tokens: usage.output_tokens,
|
|
109
|
-
|
|
128
|
+
cache_write_tokens: usage.cache_write_input_tokens,
|
|
110
129
|
cache_read_tokens: usage.cache_read_input_tokens
|
|
111
130
|
)
|
|
112
131
|
end
|
|
@@ -177,15 +196,10 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
|
177
196
|
end
|
|
178
197
|
end
|
|
179
198
|
|
|
180
|
-
# Re-raises a Bedrock stream
|
|
181
|
-
# +Aws::BedrockRuntime::Errors+
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
# Detection is by class-name suffix: every Bedrock stream-exception struct
|
|
186
|
-
# is named +*Exception+ and has a matching +Aws::BedrockRuntime::Errors+
|
|
187
|
-
# class of the same name (generated via +DynamicErrors+ if not explicit).
|
|
188
|
-
# Non-exception events (e.g. +MessageStartEvent+) pass through silently.
|
|
199
|
+
# Re-raises a Bedrock stream-exception event as the matching
|
|
200
|
+
# +Aws::BedrockRuntime::Errors+ class. ConverseStream delivers API errors on
|
|
201
|
+
# the same channel as content, so without this a mid-stream failure would
|
|
202
|
+
# silently end the stream with no content.
|
|
189
203
|
#--
|
|
190
204
|
#: (untyped) -> void
|
|
191
205
|
def raise_if_stream_exception!(event)
|
|
@@ -261,7 +275,7 @@ class Riffer::Providers::AmazonBedrock < Riffer::Providers::Base
|
|
|
261
275
|
token_usage: Riffer::Providers::TokenUsage.new(
|
|
262
276
|
input_tokens: typed_event.usage.input_tokens,
|
|
263
277
|
output_tokens: typed_event.usage.output_tokens,
|
|
264
|
-
|
|
278
|
+
cache_write_tokens: typed_event.usage.cache_write_input_tokens,
|
|
265
279
|
cache_read_tokens: typed_event.usage.cache_read_input_tokens
|
|
266
280
|
)
|
|
267
281
|
)
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Anthropic provider for Claude models via the Anthropic API.
|
|
5
|
-
#
|
|
6
|
-
# Requires the +anthropic+ gem to be installed.
|
|
7
|
-
#
|
|
8
|
-
# See https://github.com/anthropics/anthropic-sdk-ruby
|
|
4
|
+
# Anthropic provider for Claude models via the Anthropic API. Requires the
|
|
5
|
+
# +anthropic+ gem.
|
|
9
6
|
class Riffer::Providers::Anthropic < Riffer::Providers::Base
|
|
10
7
|
WEB_SEARCH_TOOL_TYPE = "web_search_20250305" #: String
|
|
11
8
|
|
|
@@ -17,8 +14,6 @@ class Riffer::Providers::Anthropic < Riffer::Providers::Base
|
|
|
17
14
|
Riffer::Skills::XmlAdapter
|
|
18
15
|
end
|
|
19
16
|
|
|
20
|
-
# Initializes the Anthropic provider.
|
|
21
|
-
#
|
|
22
17
|
#--
|
|
23
18
|
#: (?api_key: String?, **untyped) -> void
|
|
24
19
|
def initialize(api_key: nil, **options)
|
|
@@ -91,7 +86,7 @@ class Riffer::Providers::Anthropic < Riffer::Providers::Base
|
|
|
91
86
|
Riffer::Providers::TokenUsage.new(
|
|
92
87
|
input_tokens: usage.input_tokens,
|
|
93
88
|
output_tokens: usage.output_tokens,
|
|
94
|
-
|
|
89
|
+
cache_write_tokens: usage.cache_creation_input_tokens,
|
|
95
90
|
cache_read_tokens: usage.cache_read_input_tokens
|
|
96
91
|
)
|
|
97
92
|
end
|
|
@@ -298,7 +293,7 @@ class Riffer::Providers::Anthropic < Riffer::Providers::Base
|
|
|
298
293
|
token_usage: Riffer::Providers::TokenUsage.new(
|
|
299
294
|
input_tokens: usage.input_tokens,
|
|
300
295
|
output_tokens: usage.output_tokens,
|
|
301
|
-
|
|
296
|
+
cache_write_tokens: usage.cache_creation_input_tokens,
|
|
302
297
|
cache_read_tokens: usage.cache_read_input_tokens
|
|
303
298
|
)
|
|
304
299
|
)
|
|
@@ -1,26 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Azure OpenAI provider for GPT models hosted on Azure.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# Credentials are resolved in order:
|
|
9
|
-
# 1. Keyword arguments (+api_key+, +base_url+)
|
|
10
|
-
# 2. Config (<tt>Riffer.config.azure_openai.api_key</tt> / <tt>.endpoint</tt>)
|
|
11
|
-
# 3. Environment variables (+AZURE_OPENAI_API_KEY+ / +AZURE_OPENAI_ENDPOINT+)
|
|
12
|
-
#
|
|
13
|
-
# Riffer::Providers::AzureOpenAI.new(
|
|
14
|
-
# api_key: "key",
|
|
15
|
-
# base_url: "https://my-resource.openai.azure.com"
|
|
16
|
-
# )
|
|
17
|
-
#
|
|
4
|
+
# Azure OpenAI provider for GPT models hosted on Azure. Requires the +openai+
|
|
5
|
+
# gem. Credentials resolve from kwargs, then config, then
|
|
6
|
+
# +AZURE_OPENAI_API_KEY+ / +AZURE_OPENAI_ENDPOINT+.
|
|
18
7
|
class Riffer::Providers::AzureOpenAI < Riffer::Providers::OpenAI
|
|
19
|
-
# Initializes the Azure OpenAI provider.
|
|
20
|
-
#
|
|
21
|
-
# [api_key] Azure OpenAI API key. Falls back to config, then +AZURE_OPENAI_API_KEY+.
|
|
22
|
-
# [base_url] Azure OpenAI endpoint URL. Falls back to config, then +AZURE_OPENAI_ENDPOINT+.
|
|
23
|
-
#
|
|
24
8
|
#--
|
|
25
9
|
#: (**untyped) -> void
|
|
26
10
|
def initialize(**options)
|