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
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
5
5
|
WEB_SEARCH_TOOL_TYPE: String
|
|
6
6
|
|
|
7
|
+
# The GenAI semconv well-known provider name.
|
|
8
|
+
# --
|
|
9
|
+
# : () -> String
|
|
10
|
+
def self.semconv_provider_name: () -> String
|
|
11
|
+
|
|
7
12
|
# --
|
|
8
13
|
# : (**untyped) -> void
|
|
9
14
|
def initialize: (**untyped) -> void
|
|
@@ -22,6 +27,23 @@ class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
|
22
27
|
# : (untyped) -> Riffer::Providers::TokenUsage?
|
|
23
28
|
def extract_token_usage: (untyped) -> Riffer::Providers::TokenUsage?
|
|
24
29
|
|
|
30
|
+
# --
|
|
31
|
+
# : (untyped) -> Riffer::Providers::TokenUsage
|
|
32
|
+
def build_token_usage: (untyped) -> Riffer::Providers::TokenUsage
|
|
33
|
+
|
|
34
|
+
# --
|
|
35
|
+
# : (untyped) -> Riffer::Providers::FinishReason?
|
|
36
|
+
def extract_finish_reason: (untyped) -> Riffer::Providers::FinishReason?
|
|
37
|
+
|
|
38
|
+
# The Responses API reports no finish_reason field, so one is derived.
|
|
39
|
+
# --
|
|
40
|
+
# : (untyped) -> Riffer::Providers::FinishReason?
|
|
41
|
+
def build_finish_reason: (untyped) -> Riffer::Providers::FinishReason?
|
|
42
|
+
|
|
43
|
+
# --
|
|
44
|
+
# : (untyped) -> Riffer::Providers::FinishReason
|
|
45
|
+
def incomplete_finish_reason: (untyped) -> Riffer::Providers::FinishReason
|
|
46
|
+
|
|
25
47
|
# --
|
|
26
48
|
# : (untyped) -> String
|
|
27
49
|
def extract_content: (untyped) -> String
|
|
@@ -31,48 +53,48 @@ class Riffer::Providers::OpenAI < Riffer::Providers::Base
|
|
|
31
53
|
def extract_tool_calls: (untyped) -> Array[Riffer::Messages::Assistant::ToolCall]
|
|
32
54
|
|
|
33
55
|
# --
|
|
34
|
-
# : (Hash[Symbol, untyped],
|
|
35
|
-
def execute_stream: (Hash[Symbol, untyped],
|
|
56
|
+
# : (Hash[Symbol, untyped], Riffer::Providers::_EventSink) -> void
|
|
57
|
+
def execute_stream: (Hash[Symbol, untyped], Riffer::Providers::_EventSink) -> void
|
|
36
58
|
|
|
37
59
|
# --
|
|
38
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
39
|
-
def handle_output_item_added_function_call: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
60
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
61
|
+
def handle_output_item_added_function_call: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
40
62
|
|
|
41
63
|
# --
|
|
42
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
43
|
-
def handle_output_text_delta: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
64
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
65
|
+
def handle_output_text_delta: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
44
66
|
|
|
45
67
|
# --
|
|
46
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
47
|
-
def handle_output_text_done: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
68
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
69
|
+
def handle_output_text_done: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
48
70
|
|
|
49
71
|
# --
|
|
50
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
51
|
-
def handle_reasoning_summary_text_delta: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
72
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
73
|
+
def handle_reasoning_summary_text_delta: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
52
74
|
|
|
53
75
|
# --
|
|
54
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
55
|
-
def handle_reasoning_summary_text_done: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
76
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
77
|
+
def handle_reasoning_summary_text_done: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
56
78
|
|
|
57
79
|
# --
|
|
58
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
59
|
-
def handle_function_call_arguments_delta: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
80
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
81
|
+
def handle_function_call_arguments_delta: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
60
82
|
|
|
61
83
|
# --
|
|
62
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
63
|
-
def handle_function_call_arguments_done: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
84
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
85
|
+
def handle_function_call_arguments_done: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
64
86
|
|
|
65
87
|
# --
|
|
66
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
67
|
-
def
|
|
88
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
89
|
+
def handle_response_finished: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
68
90
|
|
|
69
91
|
# --
|
|
70
|
-
# : (untyped, status: String, yielder:
|
|
71
|
-
def handle_web_search_status: (untyped, status: String, yielder:
|
|
92
|
+
# : (untyped, status: String, yielder: Riffer::Providers::_EventSink) -> void
|
|
93
|
+
def handle_web_search_status: (untyped, status: String, yielder: Riffer::Providers::_EventSink) -> void
|
|
72
94
|
|
|
73
95
|
# --
|
|
74
|
-
# : (untyped, yielder:
|
|
75
|
-
def handle_output_item_done_web_search: (untyped, yielder:
|
|
96
|
+
# : (untyped, yielder: Riffer::Providers::_EventSink) -> void
|
|
97
|
+
def handle_output_item_done_web_search: (untyped, yielder: Riffer::Providers::_EventSink) -> void
|
|
76
98
|
|
|
77
99
|
# --
|
|
78
100
|
# : (Array[Riffer::Messages::Base]) -> Array[Hash[Symbol, untyped]]
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
class Riffer::Providers::OpenRouter < Riffer::Providers::Base
|
|
8
8
|
BASE_URL: String
|
|
9
9
|
|
|
10
|
+
FINISH_REASONS: Hash[String, Symbol]
|
|
11
|
+
|
|
12
|
+
# The GenAI semconv well-known provider name.
|
|
13
|
+
# --
|
|
14
|
+
# : () -> String
|
|
15
|
+
def self.semconv_provider_name: () -> String
|
|
16
|
+
|
|
10
17
|
# --
|
|
11
18
|
# : (?api_key: String?, **untyped) -> void
|
|
12
19
|
def initialize: (?api_key: String?, **untyped) -> void
|
|
@@ -25,6 +32,18 @@ class Riffer::Providers::OpenRouter < Riffer::Providers::Base
|
|
|
25
32
|
# : (untyped) -> Riffer::Providers::TokenUsage?
|
|
26
33
|
def extract_token_usage: (untyped) -> Riffer::Providers::TokenUsage?
|
|
27
34
|
|
|
35
|
+
# --
|
|
36
|
+
# : (untyped) -> Riffer::Providers::TokenUsage
|
|
37
|
+
def build_token_usage: (untyped) -> Riffer::Providers::TokenUsage
|
|
38
|
+
|
|
39
|
+
# --
|
|
40
|
+
# : (untyped) -> Riffer::Providers::FinishReason?
|
|
41
|
+
def extract_finish_reason: (untyped) -> Riffer::Providers::FinishReason?
|
|
42
|
+
|
|
43
|
+
# --
|
|
44
|
+
# : (untyped) -> Riffer::Providers::FinishReason?
|
|
45
|
+
def build_finish_reason: (untyped) -> Riffer::Providers::FinishReason?
|
|
46
|
+
|
|
28
47
|
# --
|
|
29
48
|
# : (untyped) -> String
|
|
30
49
|
def extract_content: (untyped) -> String
|
|
@@ -34,28 +53,28 @@ class Riffer::Providers::OpenRouter < Riffer::Providers::Base
|
|
|
34
53
|
def extract_tool_calls: (untyped) -> Array[Riffer::Messages::Assistant::ToolCall]
|
|
35
54
|
|
|
36
55
|
# --
|
|
37
|
-
# : (Hash[Symbol, untyped],
|
|
38
|
-
def execute_stream: (Hash[Symbol, untyped],
|
|
56
|
+
# : (Hash[Symbol, untyped], Riffer::Providers::_EventSink) -> void
|
|
57
|
+
def execute_stream: (Hash[Symbol, untyped], Riffer::Providers::_EventSink) -> void
|
|
39
58
|
|
|
40
59
|
# --
|
|
41
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
42
|
-
def handle_stream_chunk: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
60
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
61
|
+
def handle_stream_chunk: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
43
62
|
|
|
44
63
|
# --
|
|
45
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
46
|
-
def handle_text_delta: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
64
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
65
|
+
def handle_text_delta: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
47
66
|
|
|
48
67
|
# --
|
|
49
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
50
|
-
def handle_reasoning_delta: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
68
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
69
|
+
def handle_reasoning_delta: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
51
70
|
|
|
52
71
|
# --
|
|
53
|
-
# : (untyped, state: Hash[Symbol, untyped], yielder:
|
|
54
|
-
def handle_tool_call_deltas: (untyped, state: Hash[Symbol, untyped], yielder:
|
|
72
|
+
# : (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
73
|
+
def handle_tool_call_deltas: (untyped, state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
55
74
|
|
|
56
75
|
# --
|
|
57
|
-
# : (state: Hash[Symbol, untyped], yielder:
|
|
58
|
-
def emit_tool_call_done_events: (state: Hash[Symbol, untyped], yielder:
|
|
76
|
+
# : (state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
77
|
+
def emit_tool_call_done_events: (state: Hash[Symbol, untyped], yielder: Riffer::Providers::_EventSink) -> void
|
|
59
78
|
|
|
60
79
|
# --
|
|
61
80
|
# : (untyped) -> bool
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# Registry for finding provider classes by identifier.
|
|
4
4
|
module Riffer::Providers::Repository
|
|
5
|
+
@key_for: Hash[singleton(Riffer::Providers::Base), Symbol]?
|
|
6
|
+
|
|
5
7
|
REPO: Hash[Symbol, ^() -> singleton(Riffer::Providers::Base)]
|
|
6
8
|
|
|
7
9
|
# Finds a provider class by identifier.
|
|
@@ -9,4 +11,9 @@ module Riffer::Providers::Repository
|
|
|
9
11
|
# --
|
|
10
12
|
# : ((String | Symbol)) -> singleton(Riffer::Providers::Base)?
|
|
11
13
|
def find: (String | Symbol) -> singleton(Riffer::Providers::Base)?
|
|
14
|
+
|
|
15
|
+
# Returns the registry identifier for a provider class, or nil when unregistered.
|
|
16
|
+
# --
|
|
17
|
+
# : (singleton(Riffer::Providers::Base)) -> Symbol?
|
|
18
|
+
def key_for: (singleton(Riffer::Providers::Base)) -> Symbol?
|
|
12
19
|
end
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
# Generated from lib/riffer/providers/token_usage.rb with RBS::Inline
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Normalized token usage for an LLM API call. Buckets carry the same
|
|
4
|
+
# meaning for every provider.
|
|
4
5
|
class Riffer::Providers::TokenUsage
|
|
5
|
-
# Number of tokens
|
|
6
|
+
# Number of tokens entering the context window, including cache reads and writes.
|
|
6
7
|
attr_reader input_tokens: Integer
|
|
7
8
|
|
|
8
|
-
# Number of tokens
|
|
9
|
+
# Number of tokens generated by the model, including reasoning/thinking tokens.
|
|
9
10
|
attr_reader output_tokens: Integer
|
|
10
11
|
|
|
11
|
-
#
|
|
12
|
+
# Subset of +input_tokens+ written to the provider's prompt cache, when the provider reports it.
|
|
12
13
|
attr_reader cache_write_tokens: Integer?
|
|
13
14
|
|
|
14
|
-
#
|
|
15
|
+
# Subset of +input_tokens+ read from the provider's prompt cache, when the provider reports it.
|
|
15
16
|
attr_reader cache_read_tokens: Integer?
|
|
16
17
|
|
|
18
|
+
# Cost of the call, set when the model is priced. For observability, not billing.
|
|
19
|
+
attr_reader cost: Float?
|
|
20
|
+
|
|
17
21
|
# --
|
|
18
|
-
# : (input_tokens: Integer, output_tokens: Integer, ?cache_write_tokens: Integer?, ?cache_read_tokens: Integer?) -> void
|
|
19
|
-
def initialize: (input_tokens: Integer, output_tokens: Integer, ?cache_write_tokens: Integer?, ?cache_read_tokens: Integer?) -> void
|
|
22
|
+
# : (input_tokens: Integer, output_tokens: Integer, ?cache_write_tokens: Integer?, ?cache_read_tokens: Integer?, ?cost: Float?) -> void
|
|
23
|
+
def initialize: (input_tokens: Integer, output_tokens: Integer, ?cache_write_tokens: Integer?, ?cache_read_tokens: Integer?, ?cost: Float?) -> void
|
|
20
24
|
|
|
21
25
|
# Returns the total number of tokens (input + output).
|
|
22
26
|
#
|
|
@@ -30,14 +34,20 @@ class Riffer::Providers::TokenUsage
|
|
|
30
34
|
# : (Riffer::Providers::TokenUsage) -> Riffer::Providers::TokenUsage
|
|
31
35
|
def +: (Riffer::Providers::TokenUsage) -> Riffer::Providers::TokenUsage
|
|
32
36
|
|
|
33
|
-
# Converts the token usage to a hash; cache tokens are omitted when nil.
|
|
37
|
+
# Converts the token usage to a hash; cache tokens and cost are omitted when nil.
|
|
34
38
|
# --
|
|
35
|
-
# : () -> Hash[Symbol, Integer]
|
|
36
|
-
def to_h: () -> Hash[Symbol, Integer]
|
|
39
|
+
# : () -> Hash[Symbol, (Integer | Float)]
|
|
40
|
+
def to_h: () -> Hash[Symbol, Integer | Float]
|
|
37
41
|
|
|
38
42
|
private
|
|
39
43
|
|
|
40
44
|
# --
|
|
41
45
|
# : (Integer?, Integer?) -> Integer?
|
|
42
46
|
def add_nullable: (Integer?, Integer?) -> Integer?
|
|
47
|
+
|
|
48
|
+
# nil is absorbing, not zero: one unpriced call makes the run total nil
|
|
49
|
+
# rather than silently under-reporting.
|
|
50
|
+
# --
|
|
51
|
+
# : (Float?, Float?) -> Float?
|
|
52
|
+
def add_cost: (Float?, Float?) -> Float?
|
|
43
53
|
end
|
|
@@ -3,8 +3,14 @@
|
|
|
3
3
|
# Tool the LLM calls to activate a skill and receive its instructions;
|
|
4
4
|
# registered automatically when an agent has skills configured.
|
|
5
5
|
class Riffer::Skills::ActivateTool < Riffer::Tool
|
|
6
|
-
# Activates a skill by name and returns its body.
|
|
6
|
+
# Activates a skill by name and returns its wrapped body, or a short pointer when the skill is already active.
|
|
7
7
|
# --
|
|
8
8
|
# : (context: Riffer::Agent::Context?, name: String) -> Riffer::Tools::Response
|
|
9
9
|
def call: (context: Riffer::Agent::Context?, name: String) -> Riffer::Tools::Response
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# --
|
|
14
|
+
# : (String) -> String
|
|
15
|
+
def already_active_message: (String) -> String
|
|
10
16
|
end
|
|
@@ -16,4 +16,14 @@ class Riffer::Skills::Adapter
|
|
|
16
16
|
# --
|
|
17
17
|
# : (Array[Riffer::Skills::Frontmatter]) -> String
|
|
18
18
|
def render_catalog: (Array[Riffer::Skills::Frontmatter]) -> String
|
|
19
|
+
|
|
20
|
+
# Renders an activated skill body wrapped in identifying tags.
|
|
21
|
+
# --
|
|
22
|
+
# : (Riffer::Skills::Frontmatter, String) -> String
|
|
23
|
+
def render_activation: (Riffer::Skills::Frontmatter, String) -> String
|
|
24
|
+
|
|
25
|
+
# The behavioral instructions rendered alongside the catalog.
|
|
26
|
+
# --
|
|
27
|
+
# : () -> String
|
|
28
|
+
def catalog_instructions: () -> String
|
|
19
29
|
end
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# Generated from lib/riffer/skills/context.rb with RBS::Inline
|
|
2
2
|
|
|
3
3
|
# Skills context for an agent generation cycle — coordinates discovery,
|
|
4
|
-
# activation, and prompt rendering, caching
|
|
4
|
+
# activation, and prompt rendering, caching skill bodies to avoid redundant
|
|
5
5
|
# backend reads. Exposed to tools via <tt>context.skills</tt>.
|
|
6
6
|
class Riffer::Skills::Context
|
|
7
|
-
@
|
|
7
|
+
@preactivated: Array[String]
|
|
8
|
+
|
|
9
|
+
@activated: Array[String]
|
|
8
10
|
|
|
9
|
-
@
|
|
11
|
+
@bodies: Hash[String, String]
|
|
12
|
+
|
|
13
|
+
@backend: Riffer::Skills::Backend
|
|
10
14
|
|
|
11
15
|
# Skill catalog indexed by name.
|
|
12
16
|
attr_reader skills: Hash[String, Riffer::Skills::Frontmatter]
|
|
@@ -15,12 +19,20 @@ class Riffer::Skills::Context
|
|
|
15
19
|
attr_reader adapter: Riffer::Skills::Adapter
|
|
16
20
|
|
|
17
21
|
# Optional callback invoked when a skill is first activated.
|
|
18
|
-
|
|
22
|
+
attr_accessor on_activate: (^(String) -> void)?
|
|
19
23
|
|
|
20
24
|
# --
|
|
21
25
|
# : (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void
|
|
22
26
|
def initialize: (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void
|
|
23
27
|
|
|
28
|
+
# Returns a skill's body without recording an activation.
|
|
29
|
+
#
|
|
30
|
+
# Raises Riffer::ArgumentError if the skill is not in the catalog.
|
|
31
|
+
#
|
|
32
|
+
# --
|
|
33
|
+
# : (String) -> String
|
|
34
|
+
def read: (String) -> String
|
|
35
|
+
|
|
24
36
|
# Activates a skill by name. Returns the cached body on re-activation.
|
|
25
37
|
#
|
|
26
38
|
# Raises Riffer::ArgumentError if the skill is not in the catalog.
|
|
@@ -29,6 +41,32 @@ class Riffer::Skills::Context
|
|
|
29
41
|
# : (String) -> String
|
|
30
42
|
def activate: (String) -> String
|
|
31
43
|
|
|
44
|
+
# Activates a skill and returns its body wrapped for injection as a user
|
|
45
|
+
# message.
|
|
46
|
+
#
|
|
47
|
+
# Raises Riffer::ArgumentError if the skill is not in the catalog.
|
|
48
|
+
#
|
|
49
|
+
# --
|
|
50
|
+
# : (String) -> String
|
|
51
|
+
def activation_prompt: (String) -> String
|
|
52
|
+
|
|
53
|
+
# Activates a skill whose body renders in the system prompt rather than the
|
|
54
|
+
# conversation.
|
|
55
|
+
#
|
|
56
|
+
# Raises Riffer::ArgumentError if the skill is not in the catalog.
|
|
57
|
+
#
|
|
58
|
+
# --
|
|
59
|
+
# : (String) -> void
|
|
60
|
+
def preactivate: (String) -> void
|
|
61
|
+
|
|
62
|
+
# Clears a skill's activation so the next activation is treated as the first.
|
|
63
|
+
#
|
|
64
|
+
# Raises Riffer::ArgumentError if the skill is not in the catalog.
|
|
65
|
+
#
|
|
66
|
+
# --
|
|
67
|
+
# : (String) -> void
|
|
68
|
+
def deactivate: (String) -> void
|
|
69
|
+
|
|
32
70
|
# Returns whether a skill has been activated.
|
|
33
71
|
#
|
|
34
72
|
# --
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Generated from lib/riffer/stream_events/finish_reason_done.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# Normalized reason the LLM finished, emitted once near the end of the
|
|
4
|
+
# stream; no ordering guarantee relative to TokenUsageDone.
|
|
5
|
+
class Riffer::StreamEvents::FinishReasonDone < Riffer::StreamEvents::Base
|
|
6
|
+
# The normalized finish reason (see <tt>Riffer::Providers::FinishReason::VALUES</tt>).
|
|
7
|
+
attr_reader finish_reason: Symbol
|
|
8
|
+
|
|
9
|
+
# The provider's raw finish-reason value, when one exists on the wire.
|
|
10
|
+
attr_reader raw_finish_reason: String?
|
|
11
|
+
|
|
12
|
+
# Raises Riffer::ArgumentError when +finish_reason+ is outside the
|
|
13
|
+
# normalized vocabulary.
|
|
14
|
+
# --
|
|
15
|
+
# : (finish_reason: Symbol, ?raw_finish_reason: String?, ?role: Symbol) -> void
|
|
16
|
+
def initialize: (finish_reason: Symbol, ?raw_finish_reason: String?, ?role: Symbol) -> void
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : () -> Hash[Symbol, untyped]
|
|
20
|
+
def to_h: () -> Hash[Symbol, untyped]
|
|
21
|
+
end
|
|
@@ -35,6 +35,10 @@ class Riffer::Tools::Runtime
|
|
|
35
35
|
|
|
36
36
|
private
|
|
37
37
|
|
|
38
|
+
# --
|
|
39
|
+
# : (Riffer::Messages::Assistant::ToolCall) { () -> Riffer::Tools::Response } -> [Riffer::Messages::Assistant::ToolCall, Riffer::Tools::Response]
|
|
40
|
+
def instrument_tool_call: (Riffer::Messages::Assistant::ToolCall) { () -> Riffer::Tools::Response } -> [ Riffer::Messages::Assistant::ToolCall, Riffer::Tools::Response ]
|
|
41
|
+
|
|
38
42
|
# --
|
|
39
43
|
# : (Riffer::Messages::Assistant::ToolCall, tools: Array[singleton(Riffer::Tool)], context: Riffer::Agent::Context?, ?assistant_message: Riffer::Messages::Assistant?) -> Riffer::Tools::Response
|
|
40
44
|
def dispatch_tool_call: (Riffer::Messages::Assistant::ToolCall, tools: Array[singleton(Riffer::Tool)], context: Riffer::Agent::Context?, ?assistant_message: Riffer::Messages::Assistant?) -> Riffer::Tools::Response
|
|
@@ -42,4 +46,35 @@ class Riffer::Tools::Runtime
|
|
|
42
46
|
# --
|
|
43
47
|
# : (String?) -> Hash[Symbol, untyped]
|
|
44
48
|
def parse_arguments: (String?) -> Hash[Symbol, untyped]
|
|
49
|
+
|
|
50
|
+
# Emitted outside +around_tool_call+ so host enrichment spans nest beneath it.
|
|
51
|
+
# --
|
|
52
|
+
# : [R] (Riffer::Messages::Assistant::ToolCall) { ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span)) -> R } -> R
|
|
53
|
+
def in_tool_span: [R] (Riffer::Messages::Assistant::ToolCall) { (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span) -> R } -> R
|
|
54
|
+
|
|
55
|
+
# --
|
|
56
|
+
# : (Riffer::Messages::Assistant::ToolCall) -> Hash[String, untyped]
|
|
57
|
+
def tool_span_attributes: (Riffer::Messages::Assistant::ToolCall) -> Hash[String, untyped]
|
|
58
|
+
|
|
59
|
+
# --
|
|
60
|
+
# : (Riffer::Messages::Assistant::ToolCall, String?) -> Hash[String, untyped]
|
|
61
|
+
def tool_metric_attributes: (Riffer::Messages::Assistant::ToolCall, String?) -> Hash[String, untyped]
|
|
62
|
+
|
|
63
|
+
# A returned error Response is a handled outcome, so its status stays unset —
|
|
64
|
+
# an error span status is reserved for a raised exception.
|
|
65
|
+
# --
|
|
66
|
+
# : ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span), Riffer::Tools::Response) -> void
|
|
67
|
+
def record_tool_outcome: (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span, Riffer::Tools::Response) -> void
|
|
68
|
+
|
|
69
|
+
# --
|
|
70
|
+
# : ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span), Riffer::Messages::Assistant::ToolCall) -> void
|
|
71
|
+
def capture_tool_arguments: (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span, Riffer::Messages::Assistant::ToolCall) -> void
|
|
72
|
+
|
|
73
|
+
# --
|
|
74
|
+
# : ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span), Riffer::Tools::Response) -> void
|
|
75
|
+
def capture_tool_result: (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span, Riffer::Tools::Response) -> void
|
|
76
|
+
|
|
77
|
+
# --
|
|
78
|
+
# : ((Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span)) -> bool
|
|
79
|
+
def capture_tool_content?: (Riffer::Tracing::Otel::Span | Riffer::Tracing::NoOp::Span) -> bool
|
|
45
80
|
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Generated from lib/riffer/tracing/capture.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# Serializes riffer messages into the GenAI semconv JSON message structure
|
|
4
|
+
# for opt-in span content capture. File parts become metadata-only stubs —
|
|
5
|
+
# bytes and URLs never reach a span attribute.
|
|
6
|
+
module Riffer::Tracing::Capture
|
|
7
|
+
# --
|
|
8
|
+
# : (Array[Riffer::Messages::Base]) -> String
|
|
9
|
+
def input_messages: (Array[Riffer::Messages::Base]) -> String
|
|
10
|
+
|
|
11
|
+
# --
|
|
12
|
+
# : (Array[Riffer::Messages::Base]) -> String?
|
|
13
|
+
def system_instructions: (Array[Riffer::Messages::Base]) -> String?
|
|
14
|
+
|
|
15
|
+
# --
|
|
16
|
+
# : (content: String?, tool_calls: Array[Riffer::Messages::Assistant::ToolCall], finish_reason: Symbol?) -> String
|
|
17
|
+
def output_messages: (content: String?, tool_calls: Array[Riffer::Messages::Assistant::ToolCall], finish_reason: Symbol?) -> String
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# --
|
|
22
|
+
# : (Riffer::Messages::Base) -> Hash[Symbol, untyped]?
|
|
23
|
+
def convert_message: (Riffer::Messages::Base) -> Hash[Symbol, untyped]?
|
|
24
|
+
|
|
25
|
+
# --
|
|
26
|
+
# : (String?, Array[Riffer::Messages::Assistant::ToolCall]) -> Array[Hash[Symbol, untyped]]
|
|
27
|
+
def assistant_parts: (String?, Array[Riffer::Messages::Assistant::ToolCall]) -> Array[Hash[Symbol, untyped]]
|
|
28
|
+
|
|
29
|
+
# --
|
|
30
|
+
# : (String?) -> Hash[Symbol, untyped]
|
|
31
|
+
def text_part: (String?) -> Hash[Symbol, untyped]
|
|
32
|
+
|
|
33
|
+
# --
|
|
34
|
+
# : (Riffer::Messages::Assistant::ToolCall) -> Hash[Symbol, untyped]
|
|
35
|
+
def tool_call_part: (Riffer::Messages::Assistant::ToolCall) -> Hash[Symbol, untyped]
|
|
36
|
+
|
|
37
|
+
# --
|
|
38
|
+
# : (Riffer::Messages::FilePart) -> Hash[Symbol, untyped]
|
|
39
|
+
def file_part: (Riffer::Messages::FilePart) -> Hash[Symbol, untyped]
|
|
40
|
+
|
|
41
|
+
# Semconv's tool_call part carries arguments as a JSON object; riffer holds
|
|
42
|
+
# them as a string — parse so the captured payload isn't double-encoded.
|
|
43
|
+
# --
|
|
44
|
+
# : (untyped) -> untyped
|
|
45
|
+
def parse_arguments: (untyped) -> untyped
|
|
46
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Generated from lib/riffer/tracing/no_op.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# No-op tracing backend, used when OTEL is unavailable or tracing is
|
|
4
|
+
# disabled.
|
|
5
|
+
module Riffer::Tracing::NoOp
|
|
6
|
+
# No-op stand-in for a span; answers <tt>recording?</tt> with +false+ so
|
|
7
|
+
# callers can skip expensive attribute serialization.
|
|
8
|
+
class Span
|
|
9
|
+
# --
|
|
10
|
+
# : (String, untyped) -> void
|
|
11
|
+
def set_attribute: (String, untyped) -> void
|
|
12
|
+
|
|
13
|
+
# --
|
|
14
|
+
# : (String, ?attributes: Hash[String, untyped]?) -> void
|
|
15
|
+
def add_event: (String, ?attributes: Hash[String, untyped]?) -> void
|
|
16
|
+
|
|
17
|
+
# --
|
|
18
|
+
# : (Exception) -> void
|
|
19
|
+
def record_exception: (Exception) -> void
|
|
20
|
+
|
|
21
|
+
# --
|
|
22
|
+
# : (?String) -> void
|
|
23
|
+
def error!: (?String) -> void
|
|
24
|
+
|
|
25
|
+
# --
|
|
26
|
+
# : () -> bool
|
|
27
|
+
def recording?: () -> bool
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
SPAN: Riffer::Tracing::NoOp::Span
|
|
31
|
+
|
|
32
|
+
# Yields the no-op span, ignoring all span options.
|
|
33
|
+
# --
|
|
34
|
+
# : [R] (String, **untyped) { (Riffer::Tracing::NoOp::Span) -> R } -> R
|
|
35
|
+
def in_span: [R] (String, **untyped) { (Riffer::Tracing::NoOp::Span) -> R } -> R
|
|
36
|
+
|
|
37
|
+
# Returns +nil+; there is no trace context without OTEL.
|
|
38
|
+
# --
|
|
39
|
+
# : () -> nil
|
|
40
|
+
def current_context: () -> nil
|
|
41
|
+
|
|
42
|
+
# Yields immediately; there is no context to attach.
|
|
43
|
+
# --
|
|
44
|
+
# : [R] (untyped) { () -> R } -> R
|
|
45
|
+
def with_context: [R] (untyped) { () -> R } -> R
|
|
46
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Generated from lib/riffer/tracing/otel.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# OTEL-backed tracing backend. <tt>::OpenTelemetry</tt> constants appear only
|
|
4
|
+
# inside method bodies here, so the gem loads and eager-loads cleanly when the
|
|
5
|
+
# OpenTelemetry API is absent.
|
|
6
|
+
class Riffer::Tracing::Otel
|
|
7
|
+
# :nodoc: all
|
|
8
|
+
SUPPORTED_API_VERSIONS: Gem::Requirement
|
|
9
|
+
|
|
10
|
+
# Wraps a live OTEL span behind the port's span surface, so callers never
|
|
11
|
+
# touch <tt>::OpenTelemetry</tt> constants (status objects in particular).
|
|
12
|
+
class Span
|
|
13
|
+
@otel_span: untyped
|
|
14
|
+
|
|
15
|
+
# --
|
|
16
|
+
# : (untyped) -> void
|
|
17
|
+
def initialize: (untyped) -> void
|
|
18
|
+
|
|
19
|
+
# --
|
|
20
|
+
# : (String, untyped) -> void
|
|
21
|
+
def set_attribute: (String, untyped) -> void
|
|
22
|
+
|
|
23
|
+
# --
|
|
24
|
+
# : (String, ?attributes: Hash[String, untyped]?) -> void
|
|
25
|
+
def add_event: (String, ?attributes: Hash[String, untyped]?) -> void
|
|
26
|
+
|
|
27
|
+
# --
|
|
28
|
+
# : (Exception) -> void
|
|
29
|
+
def record_exception: (Exception) -> void
|
|
30
|
+
|
|
31
|
+
# Marks the span status as error.
|
|
32
|
+
# --
|
|
33
|
+
# : (?String) -> void
|
|
34
|
+
def error!: (?String) -> void
|
|
35
|
+
|
|
36
|
+
# --
|
|
37
|
+
# : () -> bool
|
|
38
|
+
def recording?: () -> bool
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Builds a backend when the OpenTelemetry API is loadable at a supported
|
|
42
|
+
# version; returns +nil+ so resolution falls back to NoOp. +provider+
|
|
43
|
+
# defaults to the global <tt>OpenTelemetry.tracer_provider</tt>.
|
|
44
|
+
# --
|
|
45
|
+
# : (?provider: untyped) -> Riffer::Tracing::Otel?
|
|
46
|
+
def self.build: (?provider: untyped) -> Riffer::Tracing::Otel?
|
|
47
|
+
|
|
48
|
+
# Whether the OpenTelemetry API gem is loadable at a supported version.
|
|
49
|
+
# --
|
|
50
|
+
# : () -> bool
|
|
51
|
+
def self.available?: () -> bool
|
|
52
|
+
|
|
53
|
+
# Whether the given opentelemetry-api version is one riffer codes
|
|
54
|
+
# against. The gem is undeclared, so this guard is the only protection
|
|
55
|
+
# against an incompatible API.
|
|
56
|
+
# --
|
|
57
|
+
# : (Gem::Version) -> bool
|
|
58
|
+
def self.supported?: (Gem::Version) -> bool
|
|
59
|
+
|
|
60
|
+
# --
|
|
61
|
+
# : () -> Gem::Version?
|
|
62
|
+
private def self.api_version: () -> Gem::Version?
|
|
63
|
+
|
|
64
|
+
@tracer: untyped
|
|
65
|
+
|
|
66
|
+
# --
|
|
67
|
+
# : (provider: untyped) -> void
|
|
68
|
+
def initialize: (provider: untyped) -> void
|
|
69
|
+
|
|
70
|
+
# Opens an OTEL span around the block, yielding the wrapped span.
|
|
71
|
+
# --
|
|
72
|
+
# : [R] (String, attributes: Hash[String, untyped]?, kind: Symbol) { (Riffer::Tracing::Otel::Span) -> R } -> R
|
|
73
|
+
def in_span: [R] (String, attributes: Hash[String, untyped]?, kind: Symbol) { (Riffer::Tracing::Otel::Span) -> R } -> R
|
|
74
|
+
|
|
75
|
+
# Returns the active OTEL context.
|
|
76
|
+
# --
|
|
77
|
+
# : () -> untyped
|
|
78
|
+
def current_context: () -> untyped
|
|
79
|
+
|
|
80
|
+
# Runs the block with the given OTEL context active.
|
|
81
|
+
# --
|
|
82
|
+
# : [R] (untyped) { () -> R } -> R
|
|
83
|
+
def with_context: [R] (untyped) { () -> R } -> R
|
|
84
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generated from lib/riffer/tracing/stream_recorder.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# Wraps a stream yielder to observe terminal events for span stamping while
|
|
4
|
+
# forwarding every event downstream untouched.
|
|
5
|
+
class Riffer::Tracing::StreamRecorder
|
|
6
|
+
@yielder: Enumerator::Yielder
|
|
7
|
+
|
|
8
|
+
attr_reader token_usage: Riffer::Providers::TokenUsage?
|
|
9
|
+
|
|
10
|
+
attr_reader finish_reason: Symbol?
|
|
11
|
+
|
|
12
|
+
attr_reader raw_finish_reason: String?
|
|
13
|
+
|
|
14
|
+
attr_reader content: String?
|
|
15
|
+
|
|
16
|
+
attr_reader tool_calls: Array[Riffer::Messages::Assistant::ToolCall]
|
|
17
|
+
|
|
18
|
+
# --
|
|
19
|
+
# : (Enumerator::Yielder) -> void
|
|
20
|
+
def initialize: (Enumerator::Yielder) -> void
|
|
21
|
+
|
|
22
|
+
# --
|
|
23
|
+
# : (Riffer::StreamEvents::Base) -> self
|
|
24
|
+
def <<: (Riffer::StreamEvents::Base) -> self
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
# --
|
|
29
|
+
# : (Riffer::StreamEvents::Base) -> void
|
|
30
|
+
def record: (Riffer::StreamEvents::Base) -> void
|
|
31
|
+
end
|