class Riffer::Providers::Base
Constants
- WIRE_SEPARATOR
-
@rbs @current_tools: Array @rbs @current_model: String? @rbs @client: untyped @rbs self.@semconv_provider_name: String?
Public Class Methods
Source
# File lib/riffer/providers/base.rb, line 22 def self.semconv_provider_name # Anonymous classes stay uncached: a class assigned to a constant # later must pick up its real name, not a frozen "unknown". class_name = name or return "unknown" # A default rather than NotImplementedError, so enabling tracing never # breaks an otherwise-working custom provider. @semconv_provider_name ||= Riffer::Helpers::Identifier.derive(class_name.split("::").last) end
Source
# File lib/riffer/providers/base.rb, line 16 def self.skills_adapter(_model = nil) Riffer::Skills::MarkdownAdapter end
Public Instance Methods
Source
# File lib/riffer/providers/base.rb, line 99 def file_delivery(_file) :url end
Source
# File lib/riffer/providers/base.rb, line 34 def generate_text(prompt: nil, system: nil, messages: nil, model: nil, files: nil, **options) validate_input!(prompt: prompt, system: system, messages: messages) @current_tools = options[:tools] || [] #: Array[singleton(Riffer::Tool)] @current_model = model messages = normalize_messages(prompt: prompt, system: system, messages: messages, files: files) validate_normalized_messages!(messages) Riffer::Files::Resolver.new(provider: self).resolve!(messages) messages = merge_consecutive_messages(messages) params = build_request_params(messages, model, options) in_chat_span(model, messages, options) do |span| response = execute_generate(params) content = extract_content(response) tool_calls = extract_tool_calls(response) reasoning = extract_reasoning(response) token_usage = extract_token_usage(response) finish_reason = extract_finish_reason(response) structured_output = parse_structured_output(content) if options[:structured_output] && tool_calls.empty? Riffer::Tracing.record_usage(span, token_usage) record_finish_reason(span, finish_reason&.reason, finish_reason&.raw) capture_output(span, content: content, tool_calls: tool_calls, finish_reason: finish_reason&.reason) Riffer::Messages::Assistant.new( content, tool_calls: tool_calls, reasoning: reasoning, token_usage: token_usage, structured_output: structured_output, finish_reason: finish_reason&.reason, finish_reason_raw: finish_reason&.raw, ) end end
Source
# File lib/riffer/providers/base.rb, line 72 def stream_text(prompt: nil, system: nil, messages: nil, model: nil, files: nil, **options) validate_input!(prompt: prompt, system: system, messages: messages) @current_tools = options[:tools] || [] #: Array[singleton(Riffer::Tool)] @current_model = model messages = normalize_messages(prompt: prompt, system: system, messages: messages, files: files) validate_normalized_messages!(messages) Riffer::Files::Resolver.new(provider: self).resolve!(messages) messages = merge_consecutive_messages(messages) params = build_request_params(messages, model, options) # The enumerator body runs in its own fiber, where the fiber-local OTEL # context is empty — capture here so the chat span parents to the caller's # trace. trace_context = Riffer::Tracing.current_context Enumerator.new do |yielder| Riffer::Tracing.with_context(trace_context) do in_chat_span(model, messages, options) do |span| sink = span.recording? ? Riffer::Tracing::StreamRecorder.new(yielder) : yielder execute_stream(params, sink) record_stream_outcome(span, sink) if sink.is_a?(Riffer::Tracing::StreamRecorder) end end end end