riffer 0.32.1 → 0.34.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/.release-please-manifest.json +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +39 -0
- data/README.md +13 -11
- data/docs/01_OVERVIEW.md +2 -0
- data/docs/04_AGENT_LIFECYCLE.md +15 -13
- data/docs/08_MESSAGES.md +39 -5
- data/docs/09_STREAM_EVENTS.md +14 -0
- data/docs/10_CONFIGURATION.md +73 -4
- data/docs/13_SKILLS.md +62 -4
- data/docs/14_MCP.md +2 -1
- data/docs/16_TRACING.md +274 -0
- data/docs/17_METRICS.md +153 -0
- data/docs/providers/07_CUSTOM_PROVIDERS.md +44 -0
- data/lib/riffer/agent/response.rb +11 -2
- data/lib/riffer/agent/run.rb +136 -35
- data/lib/riffer/agent.rb +1 -1
- data/lib/riffer/config.rb +230 -15
- data/lib/riffer/guardrail.rb +8 -0
- data/lib/riffer/guardrails/runner.rb +58 -0
- data/lib/riffer/helpers/boolean.rb +22 -0
- data/lib/riffer/mcp/authenticated_tool.rb +14 -20
- data/lib/riffer/mcp/registration.rb +4 -4
- data/lib/riffer/mcp/tool.rb +23 -0
- data/lib/riffer/mcp/tool_factory.rb +14 -22
- data/lib/riffer/messages/assistant.rb +15 -3
- data/lib/riffer/messages/base.rb +2 -1
- data/lib/riffer/metrics/instruments.rb +31 -0
- data/lib/riffer/metrics/no_op.rb +14 -0
- data/lib/riffer/metrics/otel.rb +80 -0
- data/lib/riffer/metrics.rb +94 -0
- data/lib/riffer/providers/amazon_bedrock.rb +57 -21
- data/lib/riffer/providers/anthropic.rb +59 -24
- data/lib/riffer/providers/azure_open_ai.rb +7 -0
- data/lib/riffer/providers/base.rb +247 -15
- data/lib/riffer/providers/finish_reason.rb +27 -0
- data/lib/riffer/providers/gemini.rb +59 -11
- data/lib/riffer/providers/mock.rb +30 -9
- data/lib/riffer/providers/open_ai.rb +78 -24
- data/lib/riffer/providers/open_router.rb +56 -16
- data/lib/riffer/providers/repository.rb +9 -0
- data/lib/riffer/providers/token_usage.rb +27 -11
- data/lib/riffer/skills/activate_tool.rb +11 -2
- data/lib/riffer/skills/adapter.rb +15 -0
- data/lib/riffer/skills/context.rb +63 -11
- data/lib/riffer/skills/markdown_adapter.rb +1 -1
- data/lib/riffer/skills/xml_adapter.rb +1 -1
- data/lib/riffer/stream_events/finish_reason_done.rb +34 -0
- data/lib/riffer/tools/runtime.rb +99 -3
- data/lib/riffer/tracing/capture.rb +92 -0
- data/lib/riffer/tracing/no_op.rb +61 -0
- data/lib/riffer/tracing/otel.rb +132 -0
- data/lib/riffer/tracing/stream_recorder.rb +51 -0
- data/lib/riffer/tracing.rb +78 -0
- data/lib/riffer/version.rb +1 -1
- data/sig/_private/opentelemetry.rbs +22 -0
- data/sig/generated/riffer/agent/response.rbs +9 -2
- data/sig/generated/riffer/agent/run.rbs +28 -8
- data/sig/generated/riffer/config.rbs +162 -16
- data/sig/generated/riffer/guardrail.rbs +6 -0
- data/sig/generated/riffer/guardrails/runner.rbs +22 -0
- data/sig/generated/riffer/helpers/boolean.rbs +11 -0
- data/sig/generated/riffer/mcp/authenticated_tool.rbs +6 -8
- data/sig/generated/riffer/mcp/registration.rbs +4 -4
- data/sig/generated/riffer/mcp/tool.rbs +19 -0
- data/sig/generated/riffer/mcp/tool_factory.rbs +8 -7
- data/sig/generated/riffer/messages/assistant.rbs +10 -4
- data/sig/generated/riffer/metrics/instruments.rbs +15 -0
- data/sig/generated/riffer/metrics/no_op.rbs +10 -0
- data/sig/generated/riffer/metrics/otel.rbs +48 -0
- data/sig/generated/riffer/metrics.rbs +72 -0
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +35 -14
- data/sig/generated/riffer/providers/anthropic.rbs +41 -20
- data/sig/generated/riffer/providers/azure_open_ai.rbs +5 -0
- data/sig/generated/riffer/providers/base.rbs +78 -2
- data/sig/generated/riffer/providers/finish_reason.rbs +19 -0
- data/sig/generated/riffer/providers/gemini.rbs +25 -2
- data/sig/generated/riffer/providers/mock.rbs +16 -5
- data/sig/generated/riffer/providers/open_ai.rbs +44 -22
- data/sig/generated/riffer/providers/open_router.rbs +31 -12
- data/sig/generated/riffer/providers/repository.rbs +7 -0
- data/sig/generated/riffer/providers/token_usage.rbs +20 -10
- data/sig/generated/riffer/skills/activate_tool.rbs +7 -1
- data/sig/generated/riffer/skills/adapter.rbs +10 -0
- data/sig/generated/riffer/skills/context.rbs +42 -4
- data/sig/generated/riffer/stream_events/finish_reason_done.rbs +21 -0
- data/sig/generated/riffer/tools/runtime.rbs +35 -0
- data/sig/generated/riffer/tracing/capture.rbs +46 -0
- data/sig/generated/riffer/tracing/no_op.rbs +46 -0
- data/sig/generated/riffer/tracing/otel.rbs +84 -0
- data/sig/generated/riffer/tracing/stream_recorder.rbs +31 -0
- data/sig/generated/riffer/tracing.rbs +52 -0
- data/sig/manual/riffer/helpers/boolean.rbs +5 -0
- data/sig/manual/riffer/metrics/no_op.rbs +5 -0
- data/sig/manual/riffer/metrics.rbs +5 -0
- data/sig/manual/riffer/providers.rbs +9 -0
- data/sig/manual/riffer/tracing/capture.rbs +5 -0
- data/sig/manual/riffer/tracing/no_op.rbs +5 -0
- data/sig/manual/riffer/tracing.rbs +5 -0
- metadata +42 -6
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
# Internal tracing port — emits OTEL spans when the host bundles the
|
|
5
|
+
# OpenTelemetry API and no-ops otherwise, so riffer never declares an OTEL
|
|
6
|
+
# dependency.
|
|
7
|
+
module Riffer::Tracing # :nodoc: all
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
# @rbs @backend: untyped
|
|
11
|
+
|
|
12
|
+
MUTEX = Mutex.new #: Mutex
|
|
13
|
+
|
|
14
|
+
# The Ruby API cannot attach a schema URL to a tracer, so the semconv pin
|
|
15
|
+
# lives here as the documented contract version.
|
|
16
|
+
SCHEMA_URL = "https://opentelemetry.io/schemas/1.37.0" #: String
|
|
17
|
+
|
|
18
|
+
# Opens a span around the block, yielding the span.
|
|
19
|
+
#--
|
|
20
|
+
#: [R] (String, ?attributes: Hash[String, untyped]?, ?kind: Symbol) { (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span) -> R } -> R
|
|
21
|
+
def in_span(name, attributes: nil, kind: :internal, &block)
|
|
22
|
+
return NoOp.in_span(name, &block) unless Riffer.config.tracing.enabled
|
|
23
|
+
backend.in_span(name, attributes: attributes, kind: kind, &block)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns the active trace context, for re-attachment across fiber or
|
|
27
|
+
# thread boundaries.
|
|
28
|
+
#--
|
|
29
|
+
#: () -> untyped
|
|
30
|
+
def current_context
|
|
31
|
+
return NoOp.current_context unless Riffer.config.tracing.enabled
|
|
32
|
+
backend.current_context
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Runs the block with the given trace context active; +nil+ passes through
|
|
36
|
+
# so captures taken while tracing was dark stay harmless.
|
|
37
|
+
#--
|
|
38
|
+
#: [R] (untyped) { () -> R } -> R
|
|
39
|
+
def with_context(context, &block)
|
|
40
|
+
return NoOp.with_context(context, &block) unless Riffer.config.tracing.enabled
|
|
41
|
+
backend.with_context(context, &block)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Stamps token usage onto the span — the <tt>gen_ai.usage.*</tt> counts and,
|
|
45
|
+
# when the model was priced, <tt>riffer.cost</tt>.
|
|
46
|
+
#--
|
|
47
|
+
#: ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span), Riffer::Providers::TokenUsage?) -> void
|
|
48
|
+
def record_usage(span, usage)
|
|
49
|
+
return unless usage
|
|
50
|
+
|
|
51
|
+
span.set_attribute("gen_ai.usage.input_tokens", usage.input_tokens)
|
|
52
|
+
span.set_attribute("gen_ai.usage.output_tokens", usage.output_tokens)
|
|
53
|
+
span.set_attribute("gen_ai.usage.cache_read.input_tokens", usage.cache_read_tokens) if usage.cache_read_tokens
|
|
54
|
+
span.set_attribute("gen_ai.usage.cache_creation.input_tokens", usage.cache_write_tokens) if usage.cache_write_tokens
|
|
55
|
+
span.set_attribute("riffer.cost", usage.cost) if usage.cost
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Discards the resolved backend so the next span re-resolves it.
|
|
59
|
+
#--
|
|
60
|
+
#: () -> void
|
|
61
|
+
def reset!
|
|
62
|
+
MUTEX.synchronize { @backend = nil }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
#--
|
|
68
|
+
#: () -> untyped
|
|
69
|
+
def backend
|
|
70
|
+
@backend || MUTEX.synchronize { @backend ||= resolve_backend }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#--
|
|
74
|
+
#: () -> untyped
|
|
75
|
+
def resolve_backend
|
|
76
|
+
Riffer.config.tracing.backend || NoOp
|
|
77
|
+
end
|
|
78
|
+
end
|
data/lib/riffer/version.rb
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Minimal signatures for the `opentelemetry-api` and `opentelemetry-metrics-api`
|
|
2
|
+
# gems (undeclared, runtime detected), which ship no RBS.
|
|
3
|
+
#
|
|
4
|
+
# Only the surface used by Riffer::Tracing::Otel and Riffer::Metrics::Otel is
|
|
5
|
+
# declared.
|
|
6
|
+
module OpenTelemetry
|
|
7
|
+
def self.tracer_provider: () -> untyped
|
|
8
|
+
|
|
9
|
+
def self.meter_provider: () -> untyped
|
|
10
|
+
|
|
11
|
+
class Context
|
|
12
|
+
def self.current: () -> OpenTelemetry::Context
|
|
13
|
+
|
|
14
|
+
def self.with_current: [R] (OpenTelemetry::Context) { () -> R } -> R
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module Trace
|
|
18
|
+
class Status
|
|
19
|
+
def self.error: (?String) -> OpenTelemetry::Trace::Status
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -27,6 +27,13 @@ class Riffer::Agent::Response
|
|
|
27
27
|
# The parsed structured output, if structured output was configured.
|
|
28
28
|
attr_reader structured_output: Hash[Symbol, untyped]?
|
|
29
29
|
|
|
30
|
+
# The aggregate token usage across this run's LLM calls, if any was reported.
|
|
31
|
+
attr_reader token_usage: Riffer::Providers::TokenUsage?
|
|
32
|
+
|
|
33
|
+
# The number of LLM calls made during this run (0 when a before-guardrail
|
|
34
|
+
# blocks before any call). Distinct from the session's cumulative step count.
|
|
35
|
+
attr_reader steps: Integer
|
|
36
|
+
|
|
30
37
|
# The full message history from the agent conversation.
|
|
31
38
|
attr_reader messages: Array[Riffer::Messages::Base]
|
|
32
39
|
|
|
@@ -35,8 +42,8 @@ class Riffer::Agent::Response
|
|
|
35
42
|
attr_reader healed_tool_call_ids: Array[String]
|
|
36
43
|
|
|
37
44
|
# --
|
|
38
|
-
# : (String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String]) -> void
|
|
39
|
-
def initialize: (String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String]) -> void
|
|
45
|
+
# : (String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> void
|
|
46
|
+
def initialize: (String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?messages: Array[Riffer::Messages::Base], ?healed_tool_call_ids: Array[String], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> void
|
|
40
47
|
|
|
41
48
|
# Returns true if the response was blocked by a guardrail.
|
|
42
49
|
#
|
|
@@ -23,6 +23,10 @@ module Riffer::Agent::Run
|
|
|
23
23
|
# : (Riffer::Agent, ?stream_yielder: Enumerator::Yielder?) -> Riffer::Agent::Response
|
|
24
24
|
def run_loop: (Riffer::Agent, ?stream_yielder: Enumerator::Yielder?) -> Riffer::Agent::Response
|
|
25
25
|
|
|
26
|
+
# --
|
|
27
|
+
# : (Riffer::Agent, Enumerator::Yielder?) -> Riffer::Agent::Response
|
|
28
|
+
def execute_run: (Riffer::Agent, Enumerator::Yielder?) -> Riffer::Agent::Response
|
|
29
|
+
|
|
26
30
|
# --
|
|
27
31
|
# : (Riffer::Agent, Enumerator::Yielder) -> Riffer::Messages::Assistant
|
|
28
32
|
def accumulate_streamed_response: (Riffer::Agent, Enumerator::Yielder) -> Riffer::Messages::Assistant
|
|
@@ -32,8 +36,8 @@ module Riffer::Agent::Run
|
|
|
32
36
|
def record_modifications!: (Enumerator::Yielder?, Array[Riffer::Guardrails::Modification], Array[Riffer::Guardrails::Modification]) -> void
|
|
33
37
|
|
|
34
38
|
# --
|
|
35
|
-
# : (Riffer::Agent, Enumerator::Yielder?, Riffer::Guardrails::Tripwire, Array[Riffer::Guardrails::Modification]) -> Riffer::Agent::Response
|
|
36
|
-
def tripwire_response: (Riffer::Agent, Enumerator::Yielder?, Riffer::Guardrails::Tripwire, Array[Riffer::Guardrails::Modification]) -> Riffer::Agent::Response
|
|
39
|
+
# : (Riffer::Agent, Enumerator::Yielder?, Riffer::Guardrails::Tripwire, Array[Riffer::Guardrails::Modification], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> Riffer::Agent::Response
|
|
40
|
+
def tripwire_response: (Riffer::Agent, Enumerator::Yielder?, Riffer::Guardrails::Tripwire, Array[Riffer::Guardrails::Modification], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> Riffer::Agent::Response
|
|
37
41
|
|
|
38
42
|
# --
|
|
39
43
|
# : (Riffer::Agent, Array[Riffer::Guardrails::Modification], **untyped) -> Riffer::Agent::Response
|
|
@@ -60,12 +64,12 @@ module Riffer::Agent::Run
|
|
|
60
64
|
def execute_pending_tool_calls: (Riffer::Agent) -> void
|
|
61
65
|
|
|
62
66
|
# --
|
|
63
|
-
# : (Riffer::Agent, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::
|
|
64
|
-
def run_before_guardrails: (Riffer::Agent, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::
|
|
67
|
+
# : (Riffer::Agent, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Guardrails::Tripwire) -> void } -> void
|
|
68
|
+
def run_before_guardrails: (Riffer::Agent, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Guardrails::Tripwire) -> void } -> void
|
|
65
69
|
|
|
66
70
|
# --
|
|
67
|
-
# : (Riffer::Agent, Riffer::Messages::Assistant, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::
|
|
68
|
-
def run_after_guardrails: (Riffer::Agent, Riffer::Messages::Assistant, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::
|
|
71
|
+
# : (Riffer::Agent, Riffer::Messages::Assistant, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Guardrails::Tripwire) -> void } -> untyped
|
|
72
|
+
def run_after_guardrails: (Riffer::Agent, Riffer::Messages::Assistant, Enumerator::Yielder?, Array[Riffer::Guardrails::Modification]) { (Riffer::Guardrails::Tripwire) -> void } -> untyped
|
|
69
73
|
|
|
70
74
|
# --
|
|
71
75
|
# : (Riffer::Agent, Riffer::Messages::Assistant?) -> Hash[Symbol, untyped]?
|
|
@@ -80,8 +84,8 @@ module Riffer::Agent::Run
|
|
|
80
84
|
def merged_model_options: (Riffer::Agent) -> Hash[Symbol, untyped]
|
|
81
85
|
|
|
82
86
|
# --
|
|
83
|
-
# : (Riffer::Agent, String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String]) -> Riffer::Agent::Response
|
|
84
|
-
def build_response: (Riffer::Agent, String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String]) -> Riffer::Agent::Response
|
|
87
|
+
# : (Riffer::Agent, String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> Riffer::Agent::Response
|
|
88
|
+
def build_response: (Riffer::Agent, String, ?tripwire: Riffer::Guardrails::Tripwire?, ?modifications: Array[Riffer::Guardrails::Modification], ?interrupted: bool, ?interrupt_reason: (String | Symbol)?, ?structured_output: Hash[Symbol, untyped]?, ?healed_tool_call_ids: Array[String], ?token_usage: Riffer::Providers::TokenUsage?, ?steps: Integer) -> Riffer::Agent::Response
|
|
85
89
|
|
|
86
90
|
# Raises when +files+ are supplied without a +prompt+ — the provider needs
|
|
87
91
|
# text to anchor the attachments.
|
|
@@ -92,4 +96,20 @@ module Riffer::Agent::Run
|
|
|
92
96
|
# --
|
|
93
97
|
# : (Riffer::Agent, Riffer::Providers::TokenUsage?) -> void
|
|
94
98
|
def track_token_usage: (Riffer::Agent, Riffer::Providers::TokenUsage?) -> void
|
|
99
|
+
|
|
100
|
+
# --
|
|
101
|
+
# : (Riffer::Providers::TokenUsage?, Riffer::Providers::TokenUsage?) -> Riffer::Providers::TokenUsage?
|
|
102
|
+
def sum_usage: (Riffer::Providers::TokenUsage?, Riffer::Providers::TokenUsage?) -> Riffer::Providers::TokenUsage?
|
|
103
|
+
|
|
104
|
+
# --
|
|
105
|
+
# : (Riffer::Agent) -> Hash[String, untyped]
|
|
106
|
+
def run_span_attributes: (Riffer::Agent) -> Hash[String, untyped]
|
|
107
|
+
|
|
108
|
+
# --
|
|
109
|
+
# : (Riffer::Agent, String?) -> Hash[String, untyped]
|
|
110
|
+
def run_metric_attributes: (Riffer::Agent, String?) -> Hash[String, untyped]
|
|
111
|
+
|
|
112
|
+
# --
|
|
113
|
+
# : (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span, Riffer::Agent::Response) -> void
|
|
114
|
+
def record_run_outcome: (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span, Riffer::Agent::Response) -> void
|
|
95
115
|
end
|
|
@@ -7,15 +7,15 @@ class Riffer::Config
|
|
|
7
7
|
|
|
8
8
|
attr_accessor region(): untyped
|
|
9
9
|
|
|
10
|
-
def self.new: (?api_token
|
|
11
|
-
| (
|
|
10
|
+
def self.new: (?untyped api_token, ?untyped region) -> instance
|
|
11
|
+
| (?api_token: untyped, ?region: untyped) -> instance
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
class Anthropic < Struct[untyped]
|
|
15
15
|
attr_accessor api_key(): untyped
|
|
16
16
|
|
|
17
|
-
def self.new: (?api_key
|
|
18
|
-
| (
|
|
17
|
+
def self.new: (?untyped api_key) -> instance
|
|
18
|
+
| (?api_key: untyped) -> instance
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
class AzureOpenAI < Struct[untyped]
|
|
@@ -23,8 +23,8 @@ class Riffer::Config
|
|
|
23
23
|
|
|
24
24
|
attr_accessor endpoint(): untyped
|
|
25
25
|
|
|
26
|
-
def self.new: (?api_key
|
|
27
|
-
| (
|
|
26
|
+
def self.new: (?untyped api_key, ?untyped endpoint) -> instance
|
|
27
|
+
| (?api_key: untyped, ?endpoint: untyped) -> instance
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
class Gemini < Struct[untyped]
|
|
@@ -34,29 +34,29 @@ class Riffer::Config
|
|
|
34
34
|
|
|
35
35
|
attr_accessor read_timeout(): untyped
|
|
36
36
|
|
|
37
|
-
def self.new: (?api_key
|
|
38
|
-
| (
|
|
37
|
+
def self.new: (?untyped api_key, ?untyped open_timeout, ?untyped read_timeout) -> instance
|
|
38
|
+
| (?api_key: untyped, ?open_timeout: untyped, ?read_timeout: untyped) -> instance
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
class OpenAI < Struct[untyped]
|
|
42
42
|
attr_accessor api_key(): untyped
|
|
43
43
|
|
|
44
|
-
def self.new: (?api_key
|
|
45
|
-
| (
|
|
44
|
+
def self.new: (?untyped api_key) -> instance
|
|
45
|
+
| (?api_key: untyped) -> instance
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
class OpenRouter < Struct[untyped]
|
|
49
49
|
attr_accessor api_key(): untyped
|
|
50
50
|
|
|
51
|
-
def self.new: (?api_key
|
|
52
|
-
| (
|
|
51
|
+
def self.new: (?untyped api_key) -> instance
|
|
52
|
+
| (?api_key: untyped) -> instance
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
class Evals < Struct[untyped]
|
|
56
56
|
attr_accessor judge_model(): untyped
|
|
57
57
|
|
|
58
|
-
def self.new: (?judge_model
|
|
59
|
-
| (
|
|
58
|
+
def self.new: (?untyped judge_model) -> instance
|
|
59
|
+
| (?judge_model: untyped) -> instance
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
class Mcp < Struct[untyped]
|
|
@@ -64,8 +64,8 @@ class Riffer::Config
|
|
|
64
64
|
|
|
65
65
|
attr_accessor discovery_runner(): untyped
|
|
66
66
|
|
|
67
|
-
def self.new: (?credentials
|
|
68
|
-
| (
|
|
67
|
+
def self.new: (?untyped credentials, ?untyped discovery_runner) -> instance
|
|
68
|
+
| (?credentials: untyped, ?discovery_runner: untyped) -> instance
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
# Skills-related global configuration.
|
|
@@ -95,6 +95,143 @@ class Riffer::Config
|
|
|
95
95
|
def default_backend=: ((Riffer::Skills::Backend | Proc)?) -> void
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
# Tracing-related global configuration.
|
|
99
|
+
class Tracing
|
|
100
|
+
# Whether riffer emits OTEL spans; defaults to +true+, a no-op until a
|
|
101
|
+
# host wires an OTEL SDK.
|
|
102
|
+
attr_reader enabled: bool
|
|
103
|
+
|
|
104
|
+
# Whether LLM-call spans capture full message content
|
|
105
|
+
# (<tt>gen_ai.input.messages</tt>, <tt>gen_ai.output.messages</tt>,
|
|
106
|
+
# <tt>gen_ai.system_instructions</tt>); defaults to +false+ — message
|
|
107
|
+
# content routinely carries sensitive data.
|
|
108
|
+
attr_reader capture_messages: bool
|
|
109
|
+
|
|
110
|
+
# The backend riffer routes spans through; defaults to +nil+, a no-op.
|
|
111
|
+
# Riffer auto-detects no backend; assigning one is opt-in.
|
|
112
|
+
attr_reader backend: untyped
|
|
113
|
+
|
|
114
|
+
# --
|
|
115
|
+
# : () -> void
|
|
116
|
+
def initialize: () -> void
|
|
117
|
+
|
|
118
|
+
# Sets the enabled flag, coercing boolean-ish values so an env-var
|
|
119
|
+
# +"false"+ (truthy in Ruby) doesn't silently keep tracing on. Raises
|
|
120
|
+
# Riffer::ArgumentError on an unrecognized value.
|
|
121
|
+
# --
|
|
122
|
+
# : (untyped) -> void
|
|
123
|
+
def enabled=: (untyped) -> void
|
|
124
|
+
|
|
125
|
+
# Sets the capture_messages flag, coercing boolean-ish values so an
|
|
126
|
+
# env-var +"false"+ (truthy in Ruby) doesn't silently enable content
|
|
127
|
+
# capture. Raises Riffer::ArgumentError on an unrecognized value.
|
|
128
|
+
# --
|
|
129
|
+
# : (untyped) -> void
|
|
130
|
+
def capture_messages=: (untyped) -> void
|
|
131
|
+
|
|
132
|
+
# Sets the tracing backend riffer routes spans through. Raises
|
|
133
|
+
# Riffer::ArgumentError unless the value is +nil+ or responds to the full
|
|
134
|
+
# delegated contract: +in_span+, +current_context+, and +with_context+.
|
|
135
|
+
# --
|
|
136
|
+
# : (untyped) -> void
|
|
137
|
+
def backend=: (untyped) -> void
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Metrics-related global configuration, independent of +config.tracing+ so a
|
|
141
|
+
# host can run one signal without the other.
|
|
142
|
+
class Metrics
|
|
143
|
+
# Whether riffer records OTEL metric instruments; defaults to +true+, a
|
|
144
|
+
# no-op until a host wires an OTEL metrics SDK.
|
|
145
|
+
attr_reader enabled: bool
|
|
146
|
+
|
|
147
|
+
# The backend riffer routes measurements through; defaults to +nil+, a no-op.
|
|
148
|
+
# Riffer auto-detects no backend; assigning one is opt-in.
|
|
149
|
+
attr_reader backend: untyped
|
|
150
|
+
|
|
151
|
+
# --
|
|
152
|
+
# : () -> void
|
|
153
|
+
def initialize: () -> void
|
|
154
|
+
|
|
155
|
+
# Sets the enabled flag, coercing boolean-ish values so an env-var
|
|
156
|
+
# +"false"+ (truthy in Ruby) doesn't silently keep metrics on. Raises
|
|
157
|
+
# Riffer::ArgumentError on an unrecognized value.
|
|
158
|
+
# --
|
|
159
|
+
# : (untyped) -> void
|
|
160
|
+
def enabled=: (untyped) -> void
|
|
161
|
+
|
|
162
|
+
# Sets the metrics backend riffer routes measurements through. Raises
|
|
163
|
+
# Riffer::ArgumentError unless the value is +nil+ or responds to
|
|
164
|
+
# +record_histogram+.
|
|
165
|
+
# --
|
|
166
|
+
# : (untyped) -> void
|
|
167
|
+
def backend=: (untyped) -> void
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Consumer-configured token pricing, keyed by +provider/model+ id. Riffer
|
|
171
|
+
# ships no price table, so an unconfigured model carries no cost.
|
|
172
|
+
class Pricing
|
|
173
|
+
@rates: Hash[String, Riffer::Config::Pricing::Rates]
|
|
174
|
+
|
|
175
|
+
# Per-million-token rates for one model's four token buckets. +cache_read+
|
|
176
|
+
# and +cache_write+ fall back to the +input+ rate when unset.
|
|
177
|
+
class Rates
|
|
178
|
+
# Input rate per million tokens.
|
|
179
|
+
attr_reader input: Float
|
|
180
|
+
|
|
181
|
+
# Output rate per million tokens.
|
|
182
|
+
attr_reader output: Float
|
|
183
|
+
|
|
184
|
+
# Cache-read rate per million tokens.
|
|
185
|
+
attr_reader cache_read: Float?
|
|
186
|
+
|
|
187
|
+
# Cache-write rate per million tokens.
|
|
188
|
+
attr_reader cache_write: Float?
|
|
189
|
+
|
|
190
|
+
# --
|
|
191
|
+
# : (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
|
|
192
|
+
def initialize: (input: Float, output: Float, ?cache_read: Float?, ?cache_write: Float?) -> void
|
|
193
|
+
|
|
194
|
+
# Returns the cost for the given token counts.
|
|
195
|
+
# --
|
|
196
|
+
# : (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
|
|
197
|
+
def cost_for: (input_tokens: Integer, output_tokens: Integer, ?cache_read_tokens: Integer?, ?cache_write_tokens: Integer?) -> Float
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# --
|
|
201
|
+
# : () -> void
|
|
202
|
+
def initialize: () -> void
|
|
203
|
+
|
|
204
|
+
# Registers per-million-token rates for a +provider/model+ id/s. Raises
|
|
205
|
+
# Riffer::ArgumentError on a malformed id or a negative/non-numeric rate.
|
|
206
|
+
# --
|
|
207
|
+
# : ((String | Array[String]), input: Numeric, output: Numeric, ?cache_read: Numeric?, ?cache_write: Numeric?) -> void
|
|
208
|
+
def set: (String | Array[String], input: Numeric, output: Numeric, ?cache_read: Numeric?, ?cache_write: Numeric?) -> void
|
|
209
|
+
|
|
210
|
+
# Returns the rates registered for a +provider/model+ id.
|
|
211
|
+
# --
|
|
212
|
+
# : (String) -> Riffer::Config::Pricing::Rates?
|
|
213
|
+
def rates_for: (String) -> Riffer::Config::Pricing::Rates?
|
|
214
|
+
|
|
215
|
+
# Returns true when no rates are registered.
|
|
216
|
+
# --
|
|
217
|
+
# : () -> bool
|
|
218
|
+
def empty?: () -> bool
|
|
219
|
+
|
|
220
|
+
private
|
|
221
|
+
|
|
222
|
+
# --
|
|
223
|
+
# : (String) -> void
|
|
224
|
+
def validate_model!: (String) -> void
|
|
225
|
+
|
|
226
|
+
# --
|
|
227
|
+
# : (untyped, String) -> Float
|
|
228
|
+
def coerce_rate: (untyped, String) -> Float
|
|
229
|
+
|
|
230
|
+
# --
|
|
231
|
+
# : (untyped, String) -> Float?
|
|
232
|
+
def coerce_optional_rate: (untyped, String) -> Float?
|
|
233
|
+
end
|
|
234
|
+
|
|
98
235
|
VALID_MESSAGE_ID_STRATEGIES: untyped
|
|
99
236
|
|
|
100
237
|
# Amazon Bedrock configuration.
|
|
@@ -136,6 +273,15 @@ class Riffer::Config
|
|
|
136
273
|
# Skills-related global configuration.
|
|
137
274
|
attr_reader skills: Riffer::Config::Skills
|
|
138
275
|
|
|
276
|
+
# Tracing-related global configuration.
|
|
277
|
+
attr_reader tracing: Riffer::Config::Tracing
|
|
278
|
+
|
|
279
|
+
# Metrics-related global configuration.
|
|
280
|
+
attr_reader metrics: Riffer::Config::Metrics
|
|
281
|
+
|
|
282
|
+
# Consumer-configured per-model token pricing.
|
|
283
|
+
attr_reader pricing: Riffer::Config::Pricing
|
|
284
|
+
|
|
139
285
|
# Strategy for auto-generating message ids: +:none+ (default), +:uuid+, or
|
|
140
286
|
# +:uuidv7+. When not +:none+, messages get an +id+ at construction, and
|
|
141
287
|
# seeded messages passed to +Riffer::Agent#generate+ must carry their own.
|
|
@@ -26,6 +26,12 @@ class Riffer::Guardrail
|
|
|
26
26
|
# : (Riffer::Messages::Assistant, messages: Array[Riffer::Messages::Base], context: untyped) -> Riffer::Guardrails::Result
|
|
27
27
|
def process_output: (Riffer::Messages::Assistant, messages: Array[Riffer::Messages::Base], context: untyped) -> Riffer::Guardrails::Result
|
|
28
28
|
|
|
29
|
+
# Returns the guardrail's identifier, used as the tracing span suffix and the
|
|
30
|
+
# <tt>riffer.guardrail.name</tt> attribute; override to label the span.
|
|
31
|
+
# --
|
|
32
|
+
# : () -> String
|
|
33
|
+
def name: () -> String
|
|
34
|
+
|
|
29
35
|
# Creates a pass result that continues with unchanged data.
|
|
30
36
|
# --
|
|
31
37
|
# : (untyped) -> Riffer::Guardrails::Result
|
|
@@ -36,4 +36,26 @@ class Riffer::Guardrails::Runner
|
|
|
36
36
|
# --
|
|
37
37
|
# : (Riffer::Guardrail, untyped, messages: Array[Riffer::Messages::Base]?) -> Riffer::Guardrails::Result
|
|
38
38
|
def execute_guardrail: (Riffer::Guardrail, untyped, messages: Array[Riffer::Messages::Base]?) -> Riffer::Guardrails::Result
|
|
39
|
+
|
|
40
|
+
# --
|
|
41
|
+
# : (Riffer::Guardrail) { () -> Riffer::Guardrails::Result } -> Riffer::Guardrails::Result
|
|
42
|
+
def instrument_guardrail: (Riffer::Guardrail) { () -> Riffer::Guardrails::Result } -> Riffer::Guardrails::Result
|
|
43
|
+
|
|
44
|
+
# --
|
|
45
|
+
# : (Riffer::Guardrail, untyped, messages: Array[Riffer::Messages::Base]?) -> Riffer::Guardrails::Result
|
|
46
|
+
def run_guardrail_phase: (Riffer::Guardrail, untyped, messages: Array[Riffer::Messages::Base]?) -> Riffer::Guardrails::Result
|
|
47
|
+
|
|
48
|
+
# --
|
|
49
|
+
# : (Riffer::Guardrail) -> Hash[String, untyped]
|
|
50
|
+
def guardrail_span_attributes: (Riffer::Guardrail) -> Hash[String, untyped]
|
|
51
|
+
|
|
52
|
+
# --
|
|
53
|
+
# : (Riffer::Guardrail, String?) -> Hash[String, untyped]
|
|
54
|
+
def guardrail_metric_attributes: (Riffer::Guardrail, String?) -> Hash[String, untyped]
|
|
55
|
+
|
|
56
|
+
# A block is a handled outcome, so its span status stays unset — an error
|
|
57
|
+
# span status is reserved for a raised exception.
|
|
58
|
+
# --
|
|
59
|
+
# : ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span), Riffer::Guardrails::Result) -> void
|
|
60
|
+
def record_guardrail_outcome: (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span, Riffer::Guardrails::Result) -> void
|
|
39
61
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Generated from lib/riffer/helpers/boolean.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# Coercion for boolean-ish configuration values.
|
|
4
|
+
module Riffer::Helpers::Boolean
|
|
5
|
+
# Coerces +value+ to a boolean so an env-var +"false"+ (truthy in Ruby)
|
|
6
|
+
# doesn't silently read as +true+. Raises Riffer::ArgumentError on an
|
|
7
|
+
# unrecognized value, naming +attribute+ in the message.
|
|
8
|
+
# --
|
|
9
|
+
# : (untyped, attribute: String) -> bool
|
|
10
|
+
def coerce: (untyped, attribute: String) -> bool
|
|
11
|
+
end
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
# Generated from lib/riffer/mcp/authenticated_tool.rb with RBS::Inline
|
|
2
2
|
|
|
3
3
|
# Wraps MCP-generated tool classes so +tools/call+ resolves
|
|
4
|
-
# +Riffer.config.mcp.credentials+ per invocation,
|
|
5
|
-
# inner class.
|
|
4
|
+
# +Riffer.config.mcp.credentials+ per invocation, copying metadata from the
|
|
5
|
+
# inner class at wrap time.
|
|
6
6
|
module Riffer::Mcp::AuthenticatedTool
|
|
7
7
|
# Returns one wrapper class per inner tool, sharing +manifest+ and +matched_tags+.
|
|
8
8
|
#
|
|
9
9
|
# --
|
|
10
|
-
# : (Array[singleton(Riffer::Tool)], Riffer::Mcp::Manifest, Array[Symbol]) -> Array[singleton(Riffer::Tool)]
|
|
11
|
-
def wrap_all: (Array[singleton(Riffer::Tool)], Riffer::Mcp::Manifest, Array[Symbol]) -> Array[singleton(Riffer::Tool)]
|
|
10
|
+
# : (Array[singleton(Riffer::Mcp::Tool)], Riffer::Mcp::Manifest, Array[Symbol]) -> Array[singleton(Riffer::Mcp::Tool)]
|
|
11
|
+
def wrap_all: (Array[singleton(Riffer::Mcp::Tool)], Riffer::Mcp::Manifest, Array[Symbol]) -> Array[singleton(Riffer::Mcp::Tool)]
|
|
12
12
|
|
|
13
13
|
# --
|
|
14
|
-
# : (singleton(Riffer::Tool), Riffer::Mcp::Manifest, Array[Symbol]) -> singleton(Riffer::Tool)
|
|
15
|
-
|
|
16
|
-
# relationship for dynamically created anonymous classes, so the ignore is required.
|
|
17
|
-
def wrap_one: (singleton(Riffer::Tool), Riffer::Mcp::Manifest, Array[Symbol]) -> singleton(Riffer::Tool)
|
|
14
|
+
# : (singleton(Riffer::Mcp::Tool), Riffer::Mcp::Manifest, Array[Symbol]) -> singleton(Riffer::Mcp::Tool)
|
|
15
|
+
def wrap_one: (singleton(Riffer::Mcp::Tool), Riffer::Mcp::Manifest, Array[Symbol]) -> singleton(Riffer::Mcp::Tool)
|
|
18
16
|
end
|
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
class Riffer::Mcp::Registration
|
|
6
6
|
@cancelled: bool
|
|
7
7
|
|
|
8
|
-
@tools: Array[singleton(Riffer::Tool)]
|
|
8
|
+
@tools: Array[singleton(Riffer::Mcp::Tool)]
|
|
9
9
|
|
|
10
10
|
@mutex: Thread::Mutex
|
|
11
11
|
|
|
12
12
|
# The manifest that describes this server.
|
|
13
13
|
attr_reader manifest: Riffer::Mcp::Manifest
|
|
14
14
|
|
|
15
|
-
# Generated Riffer::Tool subclasses.
|
|
15
|
+
# Generated Riffer::Mcp::Tool subclasses.
|
|
16
16
|
#
|
|
17
17
|
# --
|
|
18
|
-
# : () -> Array[singleton(Riffer::Tool)]
|
|
19
|
-
def tools: () -> Array[singleton(Riffer::Tool)]
|
|
18
|
+
# : () -> Array[singleton(Riffer::Mcp::Tool)]
|
|
19
|
+
def tools: () -> Array[singleton(Riffer::Mcp::Tool)]
|
|
20
20
|
|
|
21
21
|
# --
|
|
22
22
|
# : (Riffer::Mcp::Manifest) -> void
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Generated from lib/riffer/mcp/tool.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# Base class for MCP-generated tools.
|
|
4
|
+
class Riffer::Mcp::Tool < Riffer::Tool
|
|
5
|
+
self.@mcp_server_tool_name: String?
|
|
6
|
+
|
|
7
|
+
self.@input_schema: Hash[Symbol, untyped]?
|
|
8
|
+
|
|
9
|
+
# Returns the unprefixed tool name used for +tools/call+ on the MCP server.
|
|
10
|
+
# --
|
|
11
|
+
# : () -> String
|
|
12
|
+
def self.mcp_server_tool_name: () -> String
|
|
13
|
+
|
|
14
|
+
# Returns the server-published input schema, falling back to the params DSL.
|
|
15
|
+
# MCP schemas are server-defined, so +strict+ is not applied to them.
|
|
16
|
+
# --
|
|
17
|
+
# : (?strict: bool) -> Hash[Symbol, untyped]
|
|
18
|
+
def self.parameters_schema: (?strict: bool) -> Hash[Symbol, untyped]
|
|
19
|
+
end
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
# Generated from lib/riffer/mcp/tool_factory.rb with RBS::Inline
|
|
2
2
|
|
|
3
|
-
# Generates anonymous Riffer::Tool subclasses from MCP tool definitions.
|
|
3
|
+
# Generates anonymous Riffer::Mcp::Tool subclasses from MCP tool definitions.
|
|
4
4
|
# Generated tools delegate +#call+ to the MCP client and skip Riffer's param
|
|
5
5
|
# validation — the MCP server validates inputs.
|
|
6
6
|
module Riffer::Mcp::ToolFactory
|
|
7
|
-
# Builds one Riffer::Tool subclass per tool definition, prefixing names
|
|
8
|
-
# the manifest name to avoid cross-server collisions (e.g.
|
|
9
|
-
# the server-side name stays on +.mcp_server_tool_name+.
|
|
7
|
+
# Builds one Riffer::Mcp::Tool subclass per tool definition, prefixing names
|
|
8
|
+
# with the manifest name to avoid cross-server collisions (e.g.
|
|
9
|
+
# +jira__search+); the server-side name stays on +.mcp_server_tool_name+.
|
|
10
10
|
# --
|
|
11
|
-
# : (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Tool)]
|
|
12
|
-
def build: (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Tool)]
|
|
11
|
+
# : (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Mcp::Tool)]
|
|
12
|
+
def build: (String, Riffer::Mcp::Client, Array[Hash[Symbol, untyped]]) -> Array[singleton(Riffer::Mcp::Tool)]
|
|
13
13
|
|
|
14
14
|
private
|
|
15
15
|
|
|
16
16
|
# : (String) -> String
|
|
17
17
|
def sanitize_name_component: (String) -> String
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
# : (String, Riffer::Mcp::Client, Hash[Symbol, untyped]) -> singleton(Riffer::Mcp::Tool)
|
|
20
|
+
def build_tool_class: (String, Riffer::Mcp::Client, Hash[Symbol, untyped]) -> singleton(Riffer::Mcp::Tool)
|
|
20
21
|
end
|
|
@@ -10,8 +10,8 @@ class Riffer::Messages::Assistant < Riffer::Messages::Base
|
|
|
10
10
|
|
|
11
11
|
attr_accessor arguments(): untyped
|
|
12
12
|
|
|
13
|
-
def self.new: (?call_id
|
|
14
|
-
| (
|
|
13
|
+
def self.new: (?untyped call_id, ?untyped name, ?untyped arguments) -> instance
|
|
14
|
+
| (?call_id: untyped, ?name: untyped, ?arguments: untyped) -> instance
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Array of tool calls requested by the assistant.
|
|
@@ -23,9 +23,15 @@ class Riffer::Messages::Assistant < Riffer::Messages::Base
|
|
|
23
23
|
# Parsed structured output hash, or nil when not applicable.
|
|
24
24
|
attr_reader structured_output: Hash[Symbol, untyped]?
|
|
25
25
|
|
|
26
|
+
# Normalized reason the provider finished this response, when reported (see
|
|
27
|
+
# <tt>Riffer::Providers::FinishReason::VALUES</tt>).
|
|
28
|
+
attr_reader finish_reason: Symbol?
|
|
29
|
+
|
|
30
|
+
# Raises Riffer::ArgumentError when +finish_reason+ is outside the
|
|
31
|
+
# normalized vocabulary.
|
|
26
32
|
# --
|
|
27
|
-
# : (String, ?id: String?, ?tool_calls: Array[Riffer::Messages::Assistant::ToolCall], ?token_usage: Riffer::Providers::TokenUsage?, ?structured_output: Hash[Symbol, untyped]?) -> void
|
|
28
|
-
def initialize: (String, ?id: String?, ?tool_calls: Array[Riffer::Messages::Assistant::ToolCall], ?token_usage: Riffer::Providers::TokenUsage?, ?structured_output: Hash[Symbol, untyped]?) -> void
|
|
33
|
+
# : (String, ?id: String?, ?tool_calls: Array[Riffer::Messages::Assistant::ToolCall], ?token_usage: Riffer::Providers::TokenUsage?, ?structured_output: Hash[Symbol, untyped]?, ?finish_reason: Symbol?) -> void
|
|
34
|
+
def initialize: (String, ?id: String?, ?tool_calls: Array[Riffer::Messages::Assistant::ToolCall], ?token_usage: Riffer::Providers::TokenUsage?, ?structured_output: Hash[Symbol, untyped]?, ?finish_reason: Symbol?) -> void
|
|
29
35
|
|
|
30
36
|
# --
|
|
31
37
|
# : () -> Symbol
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Generated from lib/riffer/metrics/instruments.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# The catalog of metric instruments riffer records. Each handle is a constant
|
|
4
|
+
# that resolves its backend at record time, so it survives a meter-provider swap
|
|
5
|
+
# or a runtime +enabled+ flip.
|
|
6
|
+
module Riffer::Metrics::Instruments
|
|
7
|
+
# :nodoc: all
|
|
8
|
+
OPERATION_DURATION: Riffer::Metrics::Histogram
|
|
9
|
+
|
|
10
|
+
TOKEN_USAGE: Riffer::Metrics::Histogram
|
|
11
|
+
|
|
12
|
+
COST: Riffer::Metrics::Histogram
|
|
13
|
+
|
|
14
|
+
GUARDRAIL_DURATION: Riffer::Metrics::Histogram
|
|
15
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Generated from lib/riffer/metrics/no_op.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# No-op metrics backend, used when the OpenTelemetry metrics API is unavailable
|
|
4
|
+
# or metrics are disabled.
|
|
5
|
+
module Riffer::Metrics::NoOp
|
|
6
|
+
# Ignores the measurement; there is no meter without the OTEL metrics API.
|
|
7
|
+
# --
|
|
8
|
+
# : (String, Numeric, unit: String?, description: String?, attributes: Hash[String, untyped]?) -> void
|
|
9
|
+
def record_histogram: (String, Numeric, unit: String?, description: String?, attributes: Hash[String, untyped]?) -> void
|
|
10
|
+
end
|