riffer 0.47.2 → 0.49.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/.claude/rules/comments.md +2 -4
- data/.claude/rules/rbs-inline.md +2 -12
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +42 -0
- data/docs/AGENTS.md +39 -7
- data/docs/AGENT_LIFECYCLE.md +14 -16
- data/docs/CONFIGURATION.md +23 -34
- data/docs/EVALS.md +2 -1
- data/docs/MCP.md +0 -4
- data/docs/MESSAGES.md +85 -17
- data/docs/STREAM_EVENTS.md +8 -4
- data/docs/TOOL_ADVANCED.md +1 -3
- data/docs/TRACING.md +2 -2
- data/docs/providers/AMAZON_BEDROCK.md +32 -1
- data/docs/providers/CUSTOM_PROVIDERS.md +56 -4
- data/docs/providers/GEMINI.md +1 -1
- data/docs/providers/MOCK_PROVIDER.md +17 -0
- data/docs/providers/OPENROUTER.md +18 -1
- data/docs-site/build.rb +0 -6
- data/docs-site/check.rb +1 -5
- data/lib/riffer/agent/config.rb +27 -44
- data/lib/riffer/agent/context.rb +2 -26
- data/lib/riffer/agent/outcome.rb +0 -20
- data/lib/riffer/agent/response.rb +4 -35
- data/lib/riffer/agent/run.rb +32 -48
- data/lib/riffer/agent/serializer.rb +10 -39
- data/lib/riffer/agent/session/repair.rb +3 -15
- data/lib/riffer/agent/session.rb +26 -38
- data/lib/riffer/agent/structured_output/result.rb +0 -8
- data/lib/riffer/agent/structured_output.rb +0 -7
- data/lib/riffer/agent.rb +31 -127
- data/lib/riffer/config/amazon_bedrock.rb +30 -0
- data/lib/riffer/config/anthropic.rb +21 -0
- data/lib/riffer/config/azure_open_ai.rb +30 -0
- data/lib/riffer/config/evals.rb +18 -0
- data/lib/riffer/config/files.rb +61 -0
- data/lib/riffer/config/gemini.rb +21 -0
- data/lib/riffer/config/mcp.rb +31 -0
- data/lib/riffer/config/open_ai.rb +30 -0
- data/lib/riffer/config/open_router.rb +21 -0
- data/lib/riffer/config/pricing/rates.rb +36 -0
- data/lib/riffer/config/pricing.rb +64 -0
- data/lib/riffer/config/skills.rb +38 -0
- data/lib/riffer/config/tracing.rb +43 -0
- data/lib/riffer/config.rb +3 -362
- data/lib/riffer/evals/evaluator.rb +22 -23
- data/lib/riffer/evals/evaluator_runner.rb +0 -15
- data/lib/riffer/evals/judge.rb +9 -11
- data/lib/riffer/evals/result.rb +1 -11
- data/lib/riffer/evals/run_result.rb +0 -12
- data/lib/riffer/evals/scenario_result.rb +0 -19
- data/lib/riffer/files/downloader.rb +2 -3
- data/lib/riffer/files/resolver.rb +5 -10
- data/lib/riffer/guardrail.rb +2 -22
- data/lib/riffer/guardrails/modification.rb +0 -8
- data/lib/riffer/guardrails/result.rb +0 -17
- data/lib/riffer/guardrails/runner.rb +2 -11
- data/lib/riffer/guardrails/tripwire.rb +0 -8
- data/lib/riffer/guardrails.rb +0 -2
- data/lib/riffer/helpers/boolean.rb +0 -4
- data/lib/riffer/helpers/call_or_value.rb +0 -3
- data/lib/riffer/helpers/deep_dup.rb +37 -0
- data/lib/riffer/helpers/dependencies.rb +0 -4
- data/lib/riffer/helpers/identifier.rb +3 -12
- data/lib/riffer/helpers/validate.rb +42 -0
- data/lib/riffer/mcp/authenticated_tool.rb +4 -12
- data/lib/riffer/mcp/client.rb +0 -7
- data/lib/riffer/mcp/manifest.rb +3 -7
- data/lib/riffer/mcp/registration.rb +0 -10
- data/lib/riffer/mcp/registry.rb +0 -9
- data/lib/riffer/mcp/search_tool.rb +0 -4
- data/lib/riffer/mcp/tool.rb +1 -4
- data/lib/riffer/mcp/tool_factory.rb +3 -6
- data/lib/riffer/mcp.rb +2 -23
- data/lib/riffer/messages/assistant/reasoning_part.rb +73 -0
- data/lib/riffer/messages/assistant/tool_call.rb +55 -0
- data/lib/riffer/messages/assistant.rb +43 -15
- data/lib/riffer/messages/base.rb +5 -33
- data/lib/riffer/messages/system.rb +8 -1
- data/lib/riffer/messages/tool.rb +15 -13
- data/lib/riffer/messages/{file_part.rb → user/file_part.rb} +16 -40
- data/lib/riffer/messages/user.rb +11 -4
- data/lib/riffer/params/boolean.rb +1 -5
- data/lib/riffer/params/param.rb +15 -31
- data/lib/riffer/params.rb +15 -39
- data/lib/riffer/providers/amazon_bedrock.rb +104 -44
- data/lib/riffer/providers/anthropic.rb +11 -26
- data/lib/riffer/providers/azure_open_ai.rb +3 -8
- data/lib/riffer/providers/base.rb +30 -32
- data/lib/riffer/providers/finish_reason.rb +0 -6
- data/lib/riffer/providers/gemini/client.rb +4 -17
- data/lib/riffer/providers/gemini.rb +6 -12
- data/lib/riffer/providers/mock.rb +18 -27
- data/lib/riffer/providers/open_ai.rb +12 -21
- data/lib/riffer/providers/open_router.rb +109 -33
- data/lib/riffer/providers/repository.rb +2 -14
- data/lib/riffer/providers/token_usage.rb +19 -12
- data/lib/riffer/registrable.rb +11 -45
- data/lib/riffer/runner/fibers.rb +1 -6
- data/lib/riffer/runner/sequential.rb +0 -1
- data/lib/riffer/runner/threaded.rb +0 -3
- data/lib/riffer/runner.rb +0 -3
- data/lib/riffer/skills/activate_tool.rb +0 -3
- data/lib/riffer/skills/adapter.rb +0 -8
- data/lib/riffer/skills/backend.rb +2 -7
- data/lib/riffer/skills/config.rb +13 -17
- data/lib/riffer/skills/context.rb +0 -29
- data/lib/riffer/skills/filesystem_backend.rb +0 -7
- data/lib/riffer/skills/frontmatter.rb +2 -16
- data/lib/riffer/skills/markdown_adapter.rb +3 -6
- data/lib/riffer/skills/xml_adapter.rb +0 -3
- data/lib/riffer/stream_events/base.rb +0 -3
- data/lib/riffer/stream_events/finish_reason_done.rb +1 -6
- data/lib/riffer/stream_events/guardrail_modification.rb +0 -10
- data/lib/riffer/stream_events/guardrail_tripwire.rb +0 -10
- data/lib/riffer/stream_events/interrupt.rb +2 -12
- data/lib/riffer/stream_events/reasoning_delta.rb +0 -3
- data/lib/riffer/stream_events/reasoning_done.rb +6 -8
- data/lib/riffer/stream_events/skill_activation.rb +0 -3
- data/lib/riffer/stream_events/text_delta.rb +0 -2
- data/lib/riffer/stream_events/text_done.rb +0 -2
- data/lib/riffer/stream_events/token_usage_done.rb +0 -2
- data/lib/riffer/stream_events/tool_call_delta.rb +1 -5
- data/lib/riffer/stream_events/tool_call_done.rb +0 -5
- data/lib/riffer/stream_events/web_search_done.rb +0 -3
- data/lib/riffer/stream_events/web_search_status.rb +1 -5
- data/lib/riffer/testing/minitest.rb +4 -5
- data/lib/riffer/testing.rb +5 -38
- data/lib/riffer/tool.rb +2 -28
- data/lib/riffer/tools/response.rb +3 -32
- data/lib/riffer/tools/runtime/fibers.rb +0 -6
- data/lib/riffer/tools/runtime/inline.rb +0 -1
- data/lib/riffer/tools/runtime/threaded.rb +0 -6
- data/lib/riffer/tools/runtime.rb +8 -30
- data/lib/riffer/tools/toolable.rb +0 -37
- data/lib/riffer/tracing/capture.rb +5 -9
- data/lib/riffer/tracing/no_op.rb +0 -7
- data/lib/riffer/tracing/otel.rb +7 -16
- data/lib/riffer/tracing/stream_recorder.rb +0 -7
- data/lib/riffer/tracing.rb +4 -27
- data/lib/riffer/version.rb +1 -1
- data/lib/riffer.rb +2 -30
- data/sig/generated/riffer/agent/config.rbs +24 -46
- data/sig/generated/riffer/agent/context.rbs +2 -26
- data/sig/generated/riffer/agent/outcome.rbs +0 -20
- data/sig/generated/riffer/agent/response.rbs +4 -27
- data/sig/generated/riffer/agent/run.rbs +12 -31
- data/sig/generated/riffer/agent/serializer.rbs +2 -27
- data/sig/generated/riffer/agent/session/repair.rbs +2 -10
- data/sig/generated/riffer/agent/session.rbs +10 -36
- data/sig/generated/riffer/agent/structured_output/result.rbs +0 -7
- data/sig/generated/riffer/agent/structured_output.rbs +0 -7
- data/sig/generated/riffer/agent.rbs +25 -125
- data/sig/generated/riffer/config/amazon_bedrock.rbs +21 -0
- data/sig/generated/riffer/config/anthropic.rbs +15 -0
- data/sig/generated/riffer/config/azure_open_ai.rbs +21 -0
- data/sig/generated/riffer/config/evals.rbs +13 -0
- data/sig/generated/riffer/config/files.rbs +43 -0
- data/sig/generated/riffer/config/gemini.rbs +15 -0
- data/sig/generated/riffer/config/mcp.rbs +19 -0
- data/sig/generated/riffer/config/open_ai.rbs +21 -0
- data/sig/generated/riffer/config/open_router.rbs +15 -0
- data/sig/generated/riffer/config/pricing/rates.rbs +19 -0
- data/sig/generated/riffer/config/pricing.rbs +31 -0
- data/sig/generated/riffer/config/skills.rbs +19 -0
- data/sig/generated/riffer/config/tracing.rbs +25 -0
- data/sig/generated/riffer/config.rbs +2 -307
- data/sig/generated/riffer/evals/evaluator.rbs +12 -21
- data/sig/generated/riffer/evals/evaluator_runner.rbs +0 -14
- data/sig/generated/riffer/evals/judge.rbs +4 -8
- data/sig/generated/riffer/evals/result.rbs +1 -11
- data/sig/generated/riffer/evals/run_result.rbs +0 -12
- data/sig/generated/riffer/evals/scenario_result.rbs +0 -14
- data/sig/generated/riffer/files/resolver.rbs +6 -13
- data/sig/generated/riffer/guardrail.rbs +2 -22
- data/sig/generated/riffer/guardrails/modification.rbs +0 -6
- data/sig/generated/riffer/guardrails/result.rbs +0 -15
- data/sig/generated/riffer/guardrails/runner.rbs +0 -11
- data/sig/generated/riffer/guardrails/tripwire.rbs +0 -8
- data/sig/generated/riffer/guardrails.rbs +0 -2
- data/sig/generated/riffer/helpers/boolean.rbs +0 -4
- data/sig/generated/riffer/helpers/call_or_value.rbs +0 -3
- data/sig/generated/riffer/helpers/deep_dup.rbs +13 -0
- data/sig/generated/riffer/helpers/dependencies.rbs +0 -4
- data/sig/generated/riffer/helpers/identifier.rbs +0 -12
- data/sig/generated/riffer/helpers/validate.rbs +21 -0
- data/sig/generated/riffer/mcp/authenticated_tool.rbs +0 -5
- data/sig/generated/riffer/mcp/client.rbs +0 -7
- data/sig/generated/riffer/mcp/manifest.rbs +3 -7
- data/sig/generated/riffer/mcp/registration.rbs +0 -10
- data/sig/generated/riffer/mcp/registry.rbs +0 -9
- data/sig/generated/riffer/mcp/search_tool.rbs +0 -4
- data/sig/generated/riffer/mcp/tool.rbs +0 -4
- data/sig/generated/riffer/mcp/tool_factory.rbs +0 -6
- data/sig/generated/riffer/mcp.rbs +2 -22
- data/sig/generated/riffer/messages/assistant/reasoning_part.rbs +45 -0
- data/sig/generated/riffer/messages/assistant/tool_call.rbs +34 -0
- data/sig/generated/riffer/messages/assistant.rbs +25 -31
- data/sig/generated/riffer/messages/base.rbs +0 -12
- data/sig/generated/riffer/messages/system.rbs +4 -1
- data/sig/generated/riffer/messages/tool.rbs +4 -10
- data/sig/generated/riffer/messages/user/file_part.rbs +76 -0
- data/sig/generated/riffer/messages/user.rbs +7 -5
- data/sig/generated/riffer/params/boolean.rbs +1 -4
- data/sig/generated/riffer/params/param.rbs +7 -31
- data/sig/generated/riffer/params.rbs +8 -38
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +33 -29
- data/sig/generated/riffer/providers/anthropic.rbs +2 -12
- data/sig/generated/riffer/providers/azure_open_ai.rbs +0 -8
- data/sig/generated/riffer/providers/base.rbs +18 -34
- data/sig/generated/riffer/providers/finish_reason.rbs +0 -6
- data/sig/generated/riffer/providers/gemini/client.rbs +4 -17
- data/sig/generated/riffer/providers/gemini.rbs +4 -10
- data/sig/generated/riffer/providers/mock.rbs +6 -27
- data/sig/generated/riffer/providers/open_ai.rbs +6 -13
- data/sig/generated/riffer/providers/open_router.rbs +37 -18
- data/sig/generated/riffer/providers/repository.rbs +2 -14
- data/sig/generated/riffer/providers/token_usage.rbs +9 -12
- data/sig/generated/riffer/registrable.rbs +0 -45
- data/sig/generated/riffer/runner/fibers.rbs +0 -6
- data/sig/generated/riffer/runner/sequential.rbs +0 -1
- data/sig/generated/riffer/runner/threaded.rbs +0 -3
- data/sig/generated/riffer/runner.rbs +0 -3
- data/sig/generated/riffer/skills/activate_tool.rbs +0 -3
- data/sig/generated/riffer/skills/adapter.rbs +0 -8
- data/sig/generated/riffer/skills/backend.rbs +2 -7
- data/sig/generated/riffer/skills/config.rbs +6 -17
- data/sig/generated/riffer/skills/context.rbs +0 -29
- data/sig/generated/riffer/skills/filesystem_backend.rbs +0 -7
- data/sig/generated/riffer/skills/frontmatter.rbs +2 -16
- data/sig/generated/riffer/skills/markdown_adapter.rbs +0 -6
- data/sig/generated/riffer/skills/xml_adapter.rbs +0 -3
- data/sig/generated/riffer/stream_events/base.rbs +0 -3
- data/sig/generated/riffer/stream_events/finish_reason_done.rbs +1 -6
- data/sig/generated/riffer/stream_events/guardrail_modification.rbs +0 -10
- data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +0 -10
- data/sig/generated/riffer/stream_events/interrupt.rbs +2 -10
- data/sig/generated/riffer/stream_events/reasoning_delta.rbs +0 -3
- data/sig/generated/riffer/stream_events/reasoning_done.rbs +4 -6
- data/sig/generated/riffer/stream_events/skill_activation.rbs +0 -3
- data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
- data/sig/generated/riffer/stream_events/text_done.rbs +0 -2
- data/sig/generated/riffer/stream_events/token_usage_done.rbs +0 -2
- data/sig/generated/riffer/stream_events/tool_call_delta.rbs +1 -5
- data/sig/generated/riffer/stream_events/tool_call_done.rbs +0 -5
- data/sig/generated/riffer/stream_events/web_search_done.rbs +0 -3
- data/sig/generated/riffer/stream_events/web_search_status.rbs +1 -5
- data/sig/generated/riffer/testing.rbs +0 -38
- data/sig/generated/riffer/tool.rbs +0 -27
- data/sig/generated/riffer/tools/response.rbs +3 -29
- data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -5
- data/sig/generated/riffer/tools/runtime/inline.rbs +0 -1
- data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -5
- data/sig/generated/riffer/tools/runtime.rbs +4 -26
- data/sig/generated/riffer/tools/toolable.rbs +0 -37
- data/sig/generated/riffer/tracing/capture.rbs +6 -9
- data/sig/generated/riffer/tracing/no_op.rbs +0 -7
- data/sig/generated/riffer/tracing/otel.rbs +7 -16
- data/sig/generated/riffer/tracing/stream_recorder.rbs +0 -2
- data/sig/generated/riffer/tracing.rbs +4 -23
- data/sig/generated/riffer.rbs +2 -29
- data/sig/manual/riffer/helpers/deep_dup.rbs +5 -0
- data/sig/manual/riffer/helpers/validate.rbs +5 -0
- metadata +39 -3
- data/sig/generated/riffer/messages/file_part.rbs +0 -101
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Emitted when a guardrail transforms data during streaming.
|
|
5
4
|
class Riffer::StreamEvents::GuardrailModification < Riffer::StreamEvents::Base
|
|
6
|
-
# The modification record.
|
|
7
5
|
attr_reader :modification #: Riffer::Guardrails::Modification # @dynamic modification
|
|
8
6
|
|
|
9
7
|
#--
|
|
@@ -13,26 +11,18 @@ class Riffer::StreamEvents::GuardrailModification < Riffer::StreamEvents::Base
|
|
|
13
11
|
@modification = modification
|
|
14
12
|
end
|
|
15
13
|
|
|
16
|
-
# The guardrail class that made the transformation.
|
|
17
|
-
#
|
|
18
14
|
#--
|
|
19
15
|
#: () -> singleton(Riffer::Guardrail)
|
|
20
16
|
def guardrail = modification.guardrail
|
|
21
17
|
|
|
22
|
-
# The phase when the transformation occurred.
|
|
23
|
-
#
|
|
24
18
|
#--
|
|
25
19
|
#: () -> Symbol
|
|
26
20
|
def phase = modification.phase
|
|
27
21
|
|
|
28
|
-
# The indices of messages that were changed.
|
|
29
|
-
#
|
|
30
22
|
#--
|
|
31
23
|
#: () -> Array[Integer]
|
|
32
24
|
def message_indices = modification.message_indices
|
|
33
25
|
|
|
34
|
-
# Converts the event to a hash.
|
|
35
|
-
#
|
|
36
26
|
#--
|
|
37
27
|
#: () -> Hash[Symbol, untyped]
|
|
38
28
|
def to_h
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Emitted when a guardrail blocks execution during streaming.
|
|
5
4
|
class Riffer::StreamEvents::GuardrailTripwire < Riffer::StreamEvents::Base
|
|
6
|
-
# The tripwire containing block details.
|
|
7
5
|
attr_reader :tripwire #: Riffer::Guardrails::Tripwire # @dynamic tripwire
|
|
8
6
|
|
|
9
7
|
#--
|
|
@@ -13,32 +11,24 @@ class Riffer::StreamEvents::GuardrailTripwire < Riffer::StreamEvents::Base
|
|
|
13
11
|
@tripwire = tripwire
|
|
14
12
|
end
|
|
15
13
|
|
|
16
|
-
# The reason for blocking.
|
|
17
|
-
#
|
|
18
14
|
#--
|
|
19
15
|
#: () -> String
|
|
20
16
|
def reason
|
|
21
17
|
tripwire.reason
|
|
22
18
|
end
|
|
23
19
|
|
|
24
|
-
# The phase when blocking occurred (:before or :after).
|
|
25
|
-
#
|
|
26
20
|
#--
|
|
27
21
|
#: () -> Symbol
|
|
28
22
|
def phase
|
|
29
23
|
tripwire.phase
|
|
30
24
|
end
|
|
31
25
|
|
|
32
|
-
# The guardrail class that triggered the block.
|
|
33
|
-
#
|
|
34
26
|
#--
|
|
35
27
|
#: () -> singleton(Riffer::Guardrail)
|
|
36
28
|
def guardrail
|
|
37
29
|
tripwire.guardrail
|
|
38
30
|
end
|
|
39
31
|
|
|
40
|
-
# Converts the event to a hash.
|
|
41
|
-
#
|
|
42
32
|
#--
|
|
43
33
|
#: () -> Hash[Symbol, untyped]
|
|
44
34
|
def to_h
|
|
@@ -1,31 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents an interrupt during streaming, fired when a callback throws
|
|
5
|
-
# +:riffer_interrupt+.
|
|
6
4
|
class Riffer::StreamEvents::Interrupt < Riffer::StreamEvents::Base
|
|
7
|
-
# The reason provided with the interrupt, if any.
|
|
8
5
|
attr_reader :reason #: (String | Symbol)? # @dynamic reason
|
|
9
6
|
|
|
10
|
-
# Call ids of tool_use blocks riffer filled with placeholder results when the
|
|
11
|
-
# interrupt fired (only when history healing is on).
|
|
12
|
-
attr_reader :healed_tool_call_ids #: Array[String] # @dynamic healed_tool_call_ids
|
|
13
|
-
|
|
14
7
|
#--
|
|
15
|
-
#: (?reason: (String | Symbol)
|
|
16
|
-
def initialize(reason: nil
|
|
8
|
+
#: (?reason: (String | Symbol)?) -> void
|
|
9
|
+
def initialize(reason: nil)
|
|
17
10
|
super(role: :system)
|
|
18
11
|
@reason = reason
|
|
19
|
-
@healed_tool_call_ids = healed_tool_call_ids
|
|
20
12
|
end
|
|
21
13
|
|
|
22
|
-
# Converts the event to a hash.
|
|
23
14
|
#--
|
|
24
15
|
#: () -> Hash[Symbol, untyped]
|
|
25
16
|
def to_h
|
|
26
17
|
h = { role: @role, interrupt: true } #: Hash[Symbol, untyped]
|
|
27
18
|
h[:reason] = @reason if @reason
|
|
28
|
-
h[:healed_tool_call_ids] = @healed_tool_call_ids unless @healed_tool_call_ids.empty?
|
|
29
19
|
h
|
|
30
20
|
end
|
|
31
21
|
end
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents an incremental reasoning chunk during streaming; only emitted by
|
|
5
|
-
# providers that support reasoning (e.g. OpenAI with the reasoning option).
|
|
6
4
|
class Riffer::StreamEvents::ReasoningDelta < Riffer::StreamEvents::Base
|
|
7
|
-
# The incremental reasoning content.
|
|
8
5
|
attr_reader :content #: String # @dynamic content
|
|
9
6
|
|
|
10
7
|
#--
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents completed reasoning during streaming; only emitted by providers
|
|
5
|
-
# that support reasoning (e.g. OpenAI with the reasoning option).
|
|
6
4
|
class Riffer::StreamEvents::ReasoningDone < Riffer::StreamEvents::Base
|
|
7
|
-
#
|
|
8
|
-
attr_reader :
|
|
5
|
+
# +text+ is the concatenation of the preceding ReasoningDelta events.
|
|
6
|
+
attr_reader :part #: Riffer::Messages::Assistant::ReasoningPart # @dynamic part
|
|
9
7
|
|
|
10
8
|
#--
|
|
11
|
-
#: (
|
|
12
|
-
def initialize(
|
|
9
|
+
#: (Riffer::Messages::Assistant::ReasoningPart, ?role: Symbol) -> void
|
|
10
|
+
def initialize(part, role: :assistant)
|
|
13
11
|
super(role: role)
|
|
14
|
-
@
|
|
12
|
+
@part = part
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
#--
|
|
18
16
|
#: () -> Hash[Symbol, untyped]
|
|
19
17
|
def to_h
|
|
20
|
-
{ role: @role,
|
|
18
|
+
{ role: @role, part: part.to_h }
|
|
21
19
|
end
|
|
22
20
|
end
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Emitted when a skill is activated during streaming, via the +on_activate+
|
|
5
|
-
# callback when the LLM calls the activation tool.
|
|
6
4
|
class Riffer::StreamEvents::SkillActivation < Riffer::StreamEvents::Base
|
|
7
|
-
# The activated skill name.
|
|
8
5
|
attr_reader :name #: String # @dynamic name
|
|
9
6
|
|
|
10
7
|
#--
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents an incremental text chunk during streaming.
|
|
5
4
|
class Riffer::StreamEvents::TextDelta < Riffer::StreamEvents::Base
|
|
6
|
-
# The incremental text content.
|
|
7
5
|
attr_reader :content #: String # @dynamic content
|
|
8
6
|
|
|
9
7
|
#--
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents completed text generation during streaming.
|
|
5
4
|
class Riffer::StreamEvents::TextDone < Riffer::StreamEvents::Base
|
|
6
|
-
# The complete text content.
|
|
7
5
|
attr_reader :content #: String # @dynamic content
|
|
8
6
|
|
|
9
7
|
#--
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Final token usage for the response, emitted when the LLM finishes.
|
|
5
4
|
class Riffer::StreamEvents::TokenUsageDone < Riffer::StreamEvents::Base
|
|
6
|
-
# The token usage data for this response.
|
|
7
5
|
attr_reader :token_usage #: Riffer::Providers::TokenUsage # @dynamic token_usage
|
|
8
6
|
|
|
9
7
|
#--
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents an incremental tool call chunk (partial argument data) during
|
|
5
|
-
# streaming.
|
|
6
4
|
class Riffer::StreamEvents::ToolCallDelta < Riffer::StreamEvents::Base
|
|
7
|
-
# The tool call item identifier.
|
|
8
5
|
attr_reader :item_id #: String # @dynamic item_id
|
|
9
6
|
|
|
10
|
-
#
|
|
7
|
+
# Providers may send the name only on the first delta.
|
|
11
8
|
attr_reader :name #: String? # @dynamic name
|
|
12
9
|
|
|
13
|
-
# The incremental arguments JSON fragment.
|
|
14
10
|
attr_reader :arguments_delta #: String # @dynamic arguments_delta
|
|
15
11
|
|
|
16
12
|
#--
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents a completed tool call during streaming.
|
|
5
4
|
class Riffer::StreamEvents::ToolCallDone < Riffer::StreamEvents::Base
|
|
6
|
-
# The tool call item identifier.
|
|
7
5
|
attr_reader :item_id #: String # @dynamic item_id
|
|
8
6
|
|
|
9
|
-
# The call identifier for response matching.
|
|
10
7
|
attr_reader :call_id #: String # @dynamic call_id
|
|
11
8
|
|
|
12
|
-
# The tool name.
|
|
13
9
|
attr_reader :name #: String # @dynamic name
|
|
14
10
|
|
|
15
|
-
# The complete arguments JSON string.
|
|
16
11
|
attr_reader :arguments #: String # @dynamic arguments
|
|
17
12
|
|
|
18
13
|
#--
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# The result of a completed server-side web search during streaming.
|
|
5
4
|
class Riffer::StreamEvents::WebSearchDone < Riffer::StreamEvents::Base
|
|
6
|
-
# The search query used.
|
|
7
5
|
attr_reader :query #: String # @dynamic query
|
|
8
6
|
|
|
9
|
-
# The search result sources with title and url.
|
|
10
7
|
attr_reader :sources #: Array[Hash[Symbol, String?]] # @dynamic sources
|
|
11
8
|
|
|
12
9
|
#--
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# A web search status notification, emitted as a server-side web search
|
|
5
|
-
# progresses.
|
|
6
4
|
class Riffer::StreamEvents::WebSearchStatus < Riffer::StreamEvents::Base
|
|
7
|
-
#
|
|
5
|
+
# One of "in_progress", "searching", "open_page", or "completed".
|
|
8
6
|
attr_reader :status #: String # @dynamic status
|
|
9
7
|
|
|
10
|
-
# The URL being fetched (present for "open_page" status).
|
|
11
8
|
attr_reader :url #: String? # @dynamic url
|
|
12
9
|
|
|
13
|
-
# The search query (present when available during status changes).
|
|
14
10
|
attr_reader :query #: String? # @dynamic query
|
|
15
11
|
|
|
16
12
|
#--
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rbs-inline stays disabled
|
|
4
|
-
#
|
|
5
|
-
# sig/_private/riffer/testing/minitest.rbs.
|
|
3
|
+
# rbs-inline stays disabled: a shipped signature must never name Minitest. The
|
|
4
|
+
# stub lives in sig/_private/riffer/testing/minitest.rbs.
|
|
6
5
|
|
|
7
6
|
require "riffer"
|
|
8
7
|
|
|
9
|
-
#
|
|
10
|
-
#
|
|
8
|
+
# Minitest is never a riffer dependency; the consumer's test_helper loads it
|
|
9
|
+
# before requiring this file.
|
|
11
10
|
module Riffer::Testing::MinitestCleanup
|
|
12
11
|
# Minitest reserves +after_teardown+ for library extensions; +teardown+
|
|
13
12
|
# belongs to the test author.
|
data/lib/riffer/testing.rb
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Builds throwaway agents and tools a test suite can resolve by identifier or
|
|
5
|
-
# constant name, and removes them again. Require <tt>riffer/testing/rspec</tt>
|
|
6
|
-
# or <tt>riffer/testing/minitest</tt> to get +stub_agent+/+stub_tool+ in every
|
|
7
|
-
# example plus per-test cleanup; otherwise include this module and call +reset!+
|
|
8
|
-
# from your own teardown, or call the methods on the module directly.
|
|
9
|
-
#
|
|
10
|
-
# Tracking is not synchronized — stub from a single-threaded test, before
|
|
11
|
-
# concurrent lookups begin.
|
|
12
4
|
module Riffer::Testing
|
|
13
5
|
extend self
|
|
14
6
|
|
|
@@ -17,43 +9,18 @@ module Riffer::Testing
|
|
|
17
9
|
CONST_NAME_PATTERN = /\A[A-Z][A-Za-z0-9_]*\z/ #: Regexp
|
|
18
10
|
private_constant :CONST_NAME_PATTERN
|
|
19
11
|
|
|
20
|
-
# Builds an agent class, evaluates the optional body in it, and makes it
|
|
21
|
-
# resolvable until the next +reset!+. A +name+ assigns a top-level constant
|
|
22
|
-
# and derives the identifier; the body may set +identifier+ like any other
|
|
23
|
-
# agent config.
|
|
24
|
-
#
|
|
25
|
-
# agent = stub_agent("SupportAgent") { model "mock/gpt-5-mini" }
|
|
26
|
-
#
|
|
27
|
-
# Raises Riffer::ArgumentError when the constant is already defined or the
|
|
28
|
-
# stub ends up with no identifier, and Riffer::DuplicateIdentifierError when
|
|
29
|
-
# another agent already holds the identifier.
|
|
30
|
-
#
|
|
31
12
|
#--
|
|
32
13
|
#: (?(String | Symbol)?, ?base: singleton(Riffer::Agent)) ?{ () [self: singleton(Riffer::Agent)] -> void } -> singleton(Riffer::Agent)
|
|
33
14
|
def stub_agent(name = nil, base: Riffer::Agent, &body)
|
|
34
15
|
build_stub(name, base: base, &body) #: singleton(Riffer::Agent)
|
|
35
16
|
end
|
|
36
17
|
|
|
37
|
-
# Builds a tool class, evaluates the optional body in it, and makes it
|
|
38
|
-
# resolvable until the next +reset!+. A +name+ assigns a top-level constant
|
|
39
|
-
# and derives the identifier; the body may set +identifier+ like any other
|
|
40
|
-
# tool config.
|
|
41
|
-
#
|
|
42
|
-
# tool = stub_tool("KbSearch") { def call(context:, **) = text("stubbed") }
|
|
43
|
-
#
|
|
44
|
-
# Raises Riffer::ArgumentError when the constant is already defined or the
|
|
45
|
-
# stub ends up with no identifier, and Riffer::DuplicateIdentifierError when
|
|
46
|
-
# another tool already holds the identifier.
|
|
47
|
-
#
|
|
48
18
|
#--
|
|
49
19
|
#: (?(String | Symbol)?, ?base: singleton(Riffer::Tool)) ?{ () [self: singleton(Riffer::Tool)] -> void } -> singleton(Riffer::Tool)
|
|
50
20
|
def stub_tool(name = nil, base: Riffer::Tool, &body)
|
|
51
21
|
build_stub(name, base: base, &body) #: singleton(Riffer::Tool)
|
|
52
22
|
end
|
|
53
23
|
|
|
54
|
-
# Removes every stub built since the last reset — its registration and any
|
|
55
|
-
# constant it created — newest first, and forgets them. A no-op when nothing
|
|
56
|
-
# has been stubbed.
|
|
57
24
|
#--
|
|
58
25
|
#: () -> void
|
|
59
26
|
def reset!
|
|
@@ -66,12 +33,12 @@ module Riffer::Testing
|
|
|
66
33
|
tracked.clear
|
|
67
34
|
end
|
|
68
35
|
|
|
69
|
-
# The stub classes awaiting cleanup. Lives on the module rather than the
|
|
70
|
-
# caller so an including test case and a direct
|
|
71
|
-
# <tt>Riffer::Testing.stub_*</tt> call share one list.
|
|
72
36
|
#--
|
|
73
37
|
#: () -> Array[[Class, String?]]
|
|
74
38
|
def self.registrations # :nodoc:
|
|
39
|
+
# Lives on the module rather than the caller so an including test case and
|
|
40
|
+
# a direct <tt>Riffer::Testing.stub_*</tt> call share one list. Not
|
|
41
|
+
# synchronized: stub from a single-threaded test.
|
|
75
42
|
@registrations ||= []
|
|
76
43
|
end
|
|
77
44
|
|
|
@@ -118,11 +85,11 @@ module Riffer::Testing
|
|
|
118
85
|
const_name
|
|
119
86
|
end
|
|
120
87
|
|
|
121
|
-
# A test may have removed or replaced the constant itself, so never clobber
|
|
122
|
-
# one that no longer points at the stub.
|
|
123
88
|
#--
|
|
124
89
|
#: (String, Class) -> void
|
|
125
90
|
def remove_stub_const(const_name, stub)
|
|
91
|
+
# A test may have removed or replaced the constant itself, so never clobber
|
|
92
|
+
# one that no longer points at the stub.
|
|
126
93
|
return unless Object.const_defined?(const_name, false) && Object.const_get(const_name, false).equal?(stub)
|
|
127
94
|
|
|
128
95
|
Object.send(:remove_const, const_name)
|
data/lib/riffer/tool.rb
CHANGED
|
@@ -3,64 +3,36 @@
|
|
|
3
3
|
|
|
4
4
|
require "timeout"
|
|
5
5
|
|
|
6
|
-
# Base class for all tools in the Riffer framework. Subclasses must implement
|
|
7
|
-
# the +call+ method.
|
|
8
|
-
#
|
|
9
|
-
# class WeatherLookupTool < Riffer::Tool
|
|
10
|
-
# description "Provides current weather information for a specified city."
|
|
11
|
-
#
|
|
12
|
-
# params do
|
|
13
|
-
# required :city, String, description: "The city to look up"
|
|
14
|
-
# optional :units, String, default: "celsius"
|
|
15
|
-
# end
|
|
16
|
-
#
|
|
17
|
-
# def call(context:, city:, units: nil)
|
|
18
|
-
# # Implementation
|
|
19
|
-
# end
|
|
20
|
-
# end
|
|
21
|
-
#
|
|
22
6
|
class Riffer::Tool
|
|
23
7
|
extend Riffer::Tools::Toolable
|
|
24
8
|
extend Riffer::Registrable
|
|
25
9
|
|
|
26
10
|
kind :tool
|
|
27
11
|
|
|
28
|
-
# Executes the tool with the given arguments.
|
|
29
12
|
#--
|
|
30
13
|
#: (context: Riffer::Agent::Context?, **untyped) -> Riffer::Tools::Response
|
|
31
14
|
def call(context:, **kwargs)
|
|
32
15
|
raise NotImplementedError, "#{self.class} must implement #call"
|
|
33
16
|
end
|
|
34
17
|
|
|
35
|
-
# Creates a text response.
|
|
36
|
-
#
|
|
37
18
|
#--
|
|
38
19
|
#: (untyped) -> Riffer::Tools::Response
|
|
39
20
|
def text(result)
|
|
40
21
|
Riffer::Tools::Response.text(result)
|
|
41
22
|
end
|
|
42
23
|
|
|
43
|
-
# Creates a JSON response.
|
|
44
|
-
#
|
|
45
24
|
#--
|
|
46
25
|
#: (untyped) -> Riffer::Tools::Response
|
|
47
26
|
def json(result)
|
|
48
27
|
Riffer::Tools::Response.json(result)
|
|
49
28
|
end
|
|
50
29
|
|
|
51
|
-
# Creates an error response.
|
|
52
|
-
#
|
|
53
30
|
#--
|
|
54
31
|
#: (String, ?type: Symbol) -> Riffer::Tools::Response
|
|
55
32
|
def error(message, type: :execution_error)
|
|
56
33
|
Riffer::Tools::Response.error(message, type: type)
|
|
57
34
|
end
|
|
58
35
|
|
|
59
|
-
# Executes the tool with validation and timeout, folding every +StandardError+
|
|
60
|
-
# into an error Response. Anything outside +StandardError+ — an unimplemented
|
|
61
|
-
# +#call+ above all — still propagates, because a broken tool is a broken
|
|
62
|
-
# deploy rather than a bad request.
|
|
63
|
-
#
|
|
64
36
|
#--
|
|
65
37
|
#: (context: Riffer::Agent::Context?, **untyped) -> Riffer::Tools::Response
|
|
66
38
|
def call_with_validation(context:, **kwargs)
|
|
@@ -88,6 +60,8 @@ class Riffer::Tool
|
|
|
88
60
|
)
|
|
89
61
|
rescue Riffer::ToolExecutionError => e
|
|
90
62
|
Riffer::Tools::Response.error(e.message, type: :execution_error)
|
|
63
|
+
# Anything outside StandardError — an unimplemented #call above all — still
|
|
64
|
+
# propagates: a broken tool is a broken deploy, not a bad request.
|
|
91
65
|
rescue StandardError => e
|
|
92
66
|
Riffer::Tools::Response.error(
|
|
93
67
|
"Error executing tool: #{e.class}: #{e.message}",
|
|
@@ -3,39 +3,20 @@
|
|
|
3
3
|
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# class MyTool < Riffer::Tool
|
|
9
|
-
# def call(context:, **kwargs)
|
|
10
|
-
# result = perform_operation
|
|
11
|
-
# Riffer::Tools::Response.success(result)
|
|
12
|
-
# rescue MyError => e
|
|
13
|
-
# Riffer::Tools::Response.error(e.message)
|
|
14
|
-
# end
|
|
15
|
-
# end
|
|
16
|
-
#
|
|
6
|
+
# Every tool's +call+ must return one.
|
|
17
7
|
class Riffer::Tools::Response
|
|
18
8
|
# @rbs @success: bool
|
|
19
9
|
|
|
20
10
|
VALID_FORMATS = %i[text json].freeze #: Array[Symbol]
|
|
21
11
|
|
|
22
|
-
# The response content.
|
|
23
12
|
attr_reader :content #: String # @dynamic content
|
|
24
|
-
|
|
25
|
-
# The error message, or +nil+ on success.
|
|
26
13
|
attr_reader :error_message #: String? # @dynamic error_message
|
|
27
|
-
|
|
28
|
-
# The error type, or +nil+ on success.
|
|
29
14
|
attr_reader :error_type #: Symbol? # @dynamic error_type
|
|
30
15
|
|
|
31
|
-
#
|
|
32
|
-
#
|
|
16
|
+
# Kept out of every serialized form so it never reaches an LLM or a message
|
|
17
|
+
# payload.
|
|
33
18
|
attr_reader :exception #: Exception? # @dynamic exception
|
|
34
19
|
|
|
35
|
-
# Creates a success response.
|
|
36
|
-
#
|
|
37
|
-
# Raises Riffer::ArgumentError if format is invalid.
|
|
38
|
-
#
|
|
39
20
|
#--
|
|
40
21
|
#: (untyped, ?format: Symbol) -> Riffer::Tools::Response
|
|
41
22
|
def self.success(result, format: :text)
|
|
@@ -47,42 +28,32 @@ class Riffer::Tools::Response
|
|
|
47
28
|
new(content: content, success: true)
|
|
48
29
|
end
|
|
49
30
|
|
|
50
|
-
# Creates a success response with text format.
|
|
51
|
-
#
|
|
52
31
|
#--
|
|
53
32
|
#: (untyped) -> Riffer::Tools::Response
|
|
54
33
|
def self.text(result)
|
|
55
34
|
success(result, format: :text)
|
|
56
35
|
end
|
|
57
36
|
|
|
58
|
-
# Creates a success response with JSON format.
|
|
59
|
-
#
|
|
60
37
|
#--
|
|
61
38
|
#: (untyped) -> Riffer::Tools::Response
|
|
62
39
|
def self.json(result)
|
|
63
40
|
success(result, format: :json)
|
|
64
41
|
end
|
|
65
42
|
|
|
66
|
-
# Creates an error response.
|
|
67
|
-
#
|
|
68
43
|
#--
|
|
69
44
|
#: (String, ?type: Symbol, ?exception: Exception?) -> Riffer::Tools::Response
|
|
70
45
|
def self.error(message, type: :execution_error, exception: nil)
|
|
71
46
|
new(content: message, success: false, error_message: message, error_type: type, exception: exception)
|
|
72
47
|
end
|
|
73
48
|
|
|
74
|
-
# Returns true if the tool execution succeeded.
|
|
75
49
|
#--
|
|
76
50
|
#: () -> bool
|
|
77
51
|
def success? = @success
|
|
78
52
|
|
|
79
|
-
# Returns true if the tool execution failed.
|
|
80
53
|
#--
|
|
81
54
|
#: () -> bool
|
|
82
55
|
def error? = !@success
|
|
83
56
|
|
|
84
|
-
# Returns a hash representation of the response.
|
|
85
|
-
#
|
|
86
57
|
#--
|
|
87
58
|
#: () -> Hash[Symbol, untyped]
|
|
88
59
|
def to_h
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Executes tool calls concurrently using fibers via the +async+ gem.
|
|
5
|
-
#
|
|
6
|
-
# class MyAgent < Riffer::Agent
|
|
7
|
-
# tool_runtime Riffer::Tools::Runtime::Fibers
|
|
8
|
-
# end
|
|
9
|
-
#
|
|
10
4
|
class Riffer::Tools::Runtime::Fibers < Riffer::Tools::Runtime
|
|
11
5
|
#--
|
|
12
6
|
#: (?max_concurrency: Integer?) -> void
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Executes tool calls concurrently using threads.
|
|
5
|
-
#
|
|
6
|
-
# class MyAgent < Riffer::Agent
|
|
7
|
-
# tool_runtime Riffer::Tools::Runtime::Threaded
|
|
8
|
-
# end
|
|
9
|
-
#
|
|
10
4
|
class Riffer::Tools::Runtime::Threaded < Riffer::Tools::Runtime
|
|
11
5
|
DEFAULT_MAX_CONCURRENCY = 5 #: Integer
|
|
12
6
|
|