riffer 0.31.0 → 0.32.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/.agents/code-style.md +63 -4
- data/.agents/rbs-inline.md +1 -6
- data/.release-please-manifest.json +1 -1
- data/AGENTS.md +1 -2
- data/CHANGELOG.md +18 -0
- data/docs/08_MESSAGES.md +1 -1
- data/docs/14_MCP.md +50 -5
- data/docs/providers/02_AMAZON_BEDROCK.md +14 -0
- data/lib/riffer/agent/config.rb +42 -47
- data/lib/riffer/agent/context.rb +70 -50
- data/lib/riffer/agent/response.rb +4 -20
- data/lib/riffer/agent/run.rb +28 -67
- data/lib/riffer/agent/serializer.rb +22 -81
- data/lib/riffer/agent/session/repair.rb +14 -40
- data/lib/riffer/agent/session.rb +25 -67
- data/lib/riffer/agent/structured_output/result.rb +3 -11
- data/lib/riffer/agent/structured_output.rb +5 -13
- data/lib/riffer/agent.rb +74 -192
- data/lib/riffer/config.rb +34 -101
- data/lib/riffer/evals/evaluator.rb +7 -27
- data/lib/riffer/evals/evaluator_runner.rb +11 -19
- data/lib/riffer/evals/judge.rb +4 -25
- data/lib/riffer/evals/result.rb +1 -18
- data/lib/riffer/evals/run_result.rb +0 -11
- data/lib/riffer/evals/scenario_result.rb +0 -14
- data/lib/riffer/evals.rb +0 -6
- data/lib/riffer/guardrail.rb +4 -27
- data/lib/riffer/guardrails/modification.rb +0 -10
- data/lib/riffer/guardrails/result.rb +3 -30
- data/lib/riffer/guardrails/runner.rb +5 -22
- data/lib/riffer/guardrails/tripwire.rb +1 -19
- data/lib/riffer/guardrails.rb +2 -4
- data/lib/riffer/helpers/call_or_value.rb +4 -3
- data/lib/riffer/helpers/class_name_converter.rb +3 -1
- data/lib/riffer/helpers/dependencies.rb +5 -7
- data/lib/riffer/helpers.rb +0 -5
- data/lib/riffer/mcp/authenticated_tool.rb +9 -9
- data/lib/riffer/mcp/client.rb +12 -17
- data/lib/riffer/mcp/manifest.rb +13 -10
- data/lib/riffer/mcp/registration.rb +2 -11
- data/lib/riffer/mcp/registry.rb +44 -52
- data/lib/riffer/mcp/search_tool.rb +53 -0
- data/lib/riffer/mcp/tool_factory.rb +13 -18
- data/lib/riffer/mcp.rb +12 -17
- data/lib/riffer/messages/assistant.rb +2 -9
- data/lib/riffer/messages/base.rb +46 -16
- data/lib/riffer/messages/file_part.rb +32 -24
- data/lib/riffer/messages/system.rb +0 -5
- data/lib/riffer/messages/tool.rb +0 -10
- data/lib/riffer/messages/user.rb +0 -10
- data/lib/riffer/messages.rb +0 -7
- data/lib/riffer/params/boolean.rb +2 -4
- data/lib/riffer/params/param.rb +28 -39
- data/lib/riffer/params.rb +9 -21
- data/lib/riffer/providers/amazon_bedrock.rb +42 -28
- data/lib/riffer/providers/anthropic.rb +4 -9
- data/lib/riffer/providers/azure_open_ai.rb +3 -19
- data/lib/riffer/providers/base.rb +13 -26
- data/lib/riffer/providers/gemini.rb +4 -4
- data/lib/riffer/providers/mock.rb +6 -26
- data/lib/riffer/providers/open_ai.rb +6 -8
- data/lib/riffer/providers/open_router.rb +4 -10
- data/lib/riffer/providers/repository.rb +4 -3
- data/lib/riffer/providers/token_usage.rb +9 -20
- data/lib/riffer/providers.rb +0 -8
- data/lib/riffer/runner/fibers.rb +10 -16
- data/lib/riffer/runner/sequential.rb +1 -4
- data/lib/riffer/runner/threaded.rb +3 -14
- data/lib/riffer/runner.rb +2 -15
- data/lib/riffer/skills/activate_tool.rb +2 -11
- data/lib/riffer/skills/adapter.rb +4 -22
- data/lib/riffer/skills/backend.rb +7 -21
- data/lib/riffer/skills/config.rb +10 -31
- data/lib/riffer/skills/context.rb +5 -20
- data/lib/riffer/skills/filesystem_backend.rb +7 -25
- data/lib/riffer/skills/frontmatter.rb +10 -28
- data/lib/riffer/skills/markdown_adapter.rb +2 -9
- data/lib/riffer/skills/xml_adapter.rb +2 -8
- data/lib/riffer/stream_events/base.rb +1 -6
- data/lib/riffer/stream_events/guardrail_modification.rb +1 -8
- data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -8
- data/lib/riffer/stream_events/interrupt.rb +4 -7
- data/lib/riffer/stream_events/reasoning_delta.rb +2 -4
- data/lib/riffer/stream_events/reasoning_done.rb +2 -4
- data/lib/riffer/stream_events/skill_activation.rb +2 -4
- data/lib/riffer/stream_events/text_delta.rb +0 -2
- data/lib/riffer/stream_events/text_done.rb +1 -3
- data/lib/riffer/stream_events/token_usage_done.rb +1 -8
- data/lib/riffer/stream_events/tool_call_delta.rb +2 -3
- data/lib/riffer/stream_events/tool_call_done.rb +1 -3
- data/lib/riffer/stream_events/web_search_done.rb +1 -3
- data/lib/riffer/stream_events/web_search_status.rb +2 -3
- data/lib/riffer/stream_events.rb +0 -10
- data/lib/riffer/tool.rb +6 -13
- data/lib/riffer/tools/response.rb +8 -4
- data/lib/riffer/tools/runtime/fibers.rb +0 -3
- data/lib/riffer/tools/runtime/inline.rb +1 -4
- data/lib/riffer/tools/runtime/threaded.rb +0 -2
- data/lib/riffer/tools/runtime.rb +5 -38
- data/lib/riffer/tools/toolable.rb +5 -16
- data/lib/riffer/tools.rb +0 -4
- data/lib/riffer/version.rb +1 -1
- data/lib/riffer.rb +7 -8
- data/sig/generated/riffer/agent/config.rbs +29 -46
- data/sig/generated/riffer/agent/context.rbs +40 -48
- data/sig/generated/riffer/agent/response.rbs +4 -20
- data/sig/generated/riffer/agent/run.rbs +12 -61
- data/sig/generated/riffer/agent/serializer.rbs +21 -80
- data/sig/generated/riffer/agent/session/repair.rbs +12 -40
- data/sig/generated/riffer/agent/session.rbs +25 -67
- data/sig/generated/riffer/agent/structured_output/result.rbs +2 -10
- data/sig/generated/riffer/agent/structured_output.rbs +5 -12
- data/sig/generated/riffer/agent.rbs +57 -186
- data/sig/generated/riffer/config.rbs +34 -100
- data/sig/generated/riffer/evals/evaluator.rbs +7 -27
- data/sig/generated/riffer/evals/evaluator_runner.rbs +9 -19
- data/sig/generated/riffer/evals/judge.rbs +4 -24
- data/sig/generated/riffer/evals/result.rbs +1 -17
- data/sig/generated/riffer/evals/run_result.rbs +0 -10
- data/sig/generated/riffer/evals/scenario_result.rbs +0 -13
- data/sig/generated/riffer/evals.rbs +0 -6
- data/sig/generated/riffer/guardrail.rbs +4 -27
- data/sig/generated/riffer/guardrails/modification.rbs +0 -10
- data/sig/generated/riffer/guardrails/result.rbs +3 -30
- data/sig/generated/riffer/guardrails/runner.rbs +5 -22
- data/sig/generated/riffer/guardrails/tripwire.rbs +1 -19
- data/sig/generated/riffer/guardrails.rbs +2 -4
- data/sig/generated/riffer/helpers/call_or_value.rbs +4 -3
- data/sig/generated/riffer/helpers/class_name_converter.rbs +1 -1
- data/sig/generated/riffer/helpers/dependencies.rbs +3 -7
- data/sig/generated/riffer/helpers.rbs +0 -5
- data/sig/generated/riffer/mcp/authenticated_tool.rbs +5 -4
- data/sig/generated/riffer/mcp/client.rbs +10 -16
- data/sig/generated/riffer/mcp/manifest.rbs +9 -9
- data/sig/generated/riffer/mcp/registration.rbs +2 -10
- data/sig/generated/riffer/mcp/registry.rbs +11 -18
- data/sig/generated/riffer/mcp/search_tool.rbs +26 -0
- data/sig/generated/riffer/mcp/tool_factory.rbs +10 -15
- data/sig/generated/riffer/mcp.rbs +10 -17
- data/sig/generated/riffer/messages/assistant.rbs +2 -8
- data/sig/generated/riffer/messages/base.rbs +11 -16
- data/sig/generated/riffer/messages/file_part.rbs +13 -23
- data/sig/generated/riffer/messages/system.rbs +0 -4
- data/sig/generated/riffer/messages/tool.rbs +0 -9
- data/sig/generated/riffer/messages/user.rbs +0 -9
- data/sig/generated/riffer/messages.rbs +0 -7
- data/sig/generated/riffer/params/boolean.rbs +2 -4
- data/sig/generated/riffer/params/param.rbs +21 -39
- data/sig/generated/riffer/params.rbs +9 -21
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +21 -25
- data/sig/generated/riffer/providers/anthropic.rbs +2 -7
- data/sig/generated/riffer/providers/azure_open_ai.rbs +3 -18
- data/sig/generated/riffer/providers/base.rbs +9 -25
- data/sig/generated/riffer/providers/gemini.rbs +0 -2
- data/sig/generated/riffer/providers/mock.rbs +6 -26
- data/sig/generated/riffer/providers/open_ai.rbs +1 -5
- data/sig/generated/riffer/providers/open_router.rbs +4 -10
- data/sig/generated/riffer/providers/repository.rbs +2 -3
- data/sig/generated/riffer/providers/token_usage.rbs +6 -16
- data/sig/generated/riffer/providers.rbs +0 -8
- data/sig/generated/riffer/runner/fibers.rbs +8 -15
- data/sig/generated/riffer/runner/sequential.rbs +1 -3
- data/sig/generated/riffer/runner/threaded.rbs +3 -13
- data/sig/generated/riffer/runner.rbs +2 -14
- data/sig/generated/riffer/skills/activate_tool.rbs +2 -11
- data/sig/generated/riffer/skills/adapter.rbs +4 -22
- data/sig/generated/riffer/skills/backend.rbs +7 -21
- data/sig/generated/riffer/skills/config.rbs +10 -31
- data/sig/generated/riffer/skills/context.rbs +5 -20
- data/sig/generated/riffer/skills/filesystem_backend.rbs +7 -24
- data/sig/generated/riffer/skills/frontmatter.rbs +10 -27
- data/sig/generated/riffer/skills/markdown_adapter.rbs +2 -9
- data/sig/generated/riffer/skills/xml_adapter.rbs +2 -8
- data/sig/generated/riffer/stream_events/base.rbs +1 -6
- data/sig/generated/riffer/stream_events/guardrail_modification.rbs +1 -8
- data/sig/generated/riffer/stream_events/guardrail_tripwire.rbs +1 -8
- data/sig/generated/riffer/stream_events/interrupt.rbs +4 -7
- data/sig/generated/riffer/stream_events/reasoning_delta.rbs +2 -4
- data/sig/generated/riffer/stream_events/reasoning_done.rbs +2 -4
- data/sig/generated/riffer/stream_events/skill_activation.rbs +2 -4
- data/sig/generated/riffer/stream_events/text_delta.rbs +0 -2
- data/sig/generated/riffer/stream_events/text_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/token_usage_done.rbs +1 -7
- data/sig/generated/riffer/stream_events/tool_call_delta.rbs +2 -3
- data/sig/generated/riffer/stream_events/tool_call_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/web_search_done.rbs +1 -3
- data/sig/generated/riffer/stream_events/web_search_status.rbs +2 -3
- data/sig/generated/riffer/stream_events.rbs +0 -10
- data/sig/generated/riffer/tool.rbs +5 -12
- data/sig/generated/riffer/tools/response.rbs +6 -4
- data/sig/generated/riffer/tools/runtime/fibers.rbs +0 -3
- data/sig/generated/riffer/tools/runtime/inline.rbs +1 -3
- data/sig/generated/riffer/tools/runtime/threaded.rbs +0 -2
- data/sig/generated/riffer/tools/runtime.rbs +5 -37
- data/sig/generated/riffer/tools/toolable.rbs +4 -14
- data/sig/generated/riffer/tools.rbs +0 -4
- data/sig/generated/riffer.rbs +5 -4
- data/sig/manual/riffer/agent/session/repair.rbs +5 -0
- data/sig/manual/riffer/evals/evaluator_runner.rbs +5 -0
- data/sig/manual/riffer/helpers/class_name_converter.rbs +5 -0
- data/sig/manual/riffer/helpers/dependencies.rbs +5 -0
- data/sig/manual/riffer/mcp/authenticated_tool.rbs +5 -0
- data/sig/manual/riffer/mcp/registry.rbs +5 -0
- data/sig/manual/riffer/mcp/tool_factory.rbs +5 -0
- data/sig/manual/riffer/mcp.rbs +5 -0
- data/sig/manual/riffer/providers/repository.rbs +5 -0
- data/sig/manual/riffer.rbs +5 -0
- metadata +17 -9
- data/.agents/rdoc.md +0 -69
- data/lib/riffer/messages/converter.rb +0 -90
- data/sig/generated/riffer/messages/converter.rbs +0 -33
- data/sig/manual/riffer/tools/toolable.rbs +0 -6
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Skills context for an agent generation cycle
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# Tracks activations with caching to avoid redundant backend reads.
|
|
8
|
-
#
|
|
9
|
-
# Built by the agent during +Agent.new+ and exposed to tools via
|
|
10
|
-
# <tt>context.skills</tt> on the agent's +Riffer::Agent::Context+.
|
|
11
|
-
#
|
|
12
|
-
# See Riffer::Skills::Backend, Riffer::Skills::Frontmatter.
|
|
4
|
+
# Skills context for an agent generation cycle — coordinates discovery,
|
|
5
|
+
# activation, and prompt rendering, caching activations to avoid redundant
|
|
6
|
+
# backend reads. Exposed to tools via <tt>context.skills</tt>.
|
|
13
7
|
class Riffer::Skills::Context
|
|
14
8
|
# @rbs @backend: Riffer::Skills::Backend
|
|
15
9
|
# @rbs @activated: Hash[String, String]
|
|
@@ -23,13 +17,6 @@ class Riffer::Skills::Context
|
|
|
23
17
|
# Optional callback invoked when a skill is first activated.
|
|
24
18
|
attr_writer :on_activate #: (^(String) -> void)?
|
|
25
19
|
|
|
26
|
-
# Creates a new skills context for a generation cycle.
|
|
27
|
-
#
|
|
28
|
-
# [backend] the skills backend for reading skill bodies.
|
|
29
|
-
# [skills] skill catalog indexed by name.
|
|
30
|
-
# [adapter] the adapter used to render skill content. The adapter
|
|
31
|
-
# carries the activation tool class via its initializer.
|
|
32
|
-
#
|
|
33
20
|
#--
|
|
34
21
|
#: (backend: Riffer::Skills::Backend, skills: Hash[String, Riffer::Skills::Frontmatter], adapter: Riffer::Skills::Adapter) -> void
|
|
35
22
|
def initialize(backend:, skills:, adapter:)
|
|
@@ -61,10 +48,8 @@ class Riffer::Skills::Context
|
|
|
61
48
|
@activated.key?(name)
|
|
62
49
|
end
|
|
63
50
|
|
|
64
|
-
# Returns the complete skills section for the system prompt
|
|
65
|
-
#
|
|
66
|
-
# Includes the catalog and any pre-activated skill bodies.
|
|
67
|
-
#
|
|
51
|
+
# Returns the complete skills section for the system prompt — the catalog plus
|
|
52
|
+
# any pre-activated skill bodies.
|
|
68
53
|
#--
|
|
69
54
|
#: () -> String
|
|
70
55
|
def system_prompt
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Built-in backend that reads skills from the filesystem.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# +SKILL.md+ files. Directory names must match the skill +name+ field.
|
|
8
|
-
#
|
|
9
|
-
# backend = Riffer::Skills::FilesystemBackend.new(".skills", "~/.riffer/skills")
|
|
10
|
-
# backend.list_skills # => [Riffer::Skills::Frontmatter, ...]
|
|
11
|
-
# backend.read_skill("code-review") # => "Full skill instructions..."
|
|
12
|
-
#
|
|
4
|
+
# Built-in backend that reads skills from the filesystem. Scans configured
|
|
5
|
+
# directories for immediate child directories containing +SKILL.md+; directory
|
|
6
|
+
# names must match the skill +name+.
|
|
13
7
|
class Riffer::Skills::FilesystemBackend < Riffer::Skills::Backend
|
|
14
8
|
# @rbs @paths: Array[String]
|
|
15
9
|
# @rbs @skills_cache: Hash[String, String]?
|
|
16
10
|
|
|
17
|
-
# Creates a new FilesystemBackend.
|
|
18
|
-
#
|
|
19
|
-
# [paths] one or more directory paths to scan for skills.
|
|
20
|
-
#
|
|
21
11
|
#--
|
|
22
12
|
#: (*String) -> void
|
|
23
13
|
def initialize(*paths)
|
|
@@ -25,12 +15,8 @@ class Riffer::Skills::FilesystemBackend < Riffer::Skills::Backend
|
|
|
25
15
|
@skills_cache = nil #: Hash[String, String]?
|
|
26
16
|
end
|
|
27
17
|
|
|
28
|
-
# Returns frontmatter for all discovered skills
|
|
29
|
-
#
|
|
30
|
-
# Scans each configured path for immediate child directories containing
|
|
31
|
-
# SKILL.md. When multiple paths contain a skill with the same name,
|
|
32
|
-
# first-path-wins.
|
|
33
|
-
#
|
|
18
|
+
# Returns frontmatter for all discovered skills; on a name collision across
|
|
19
|
+
# paths, first-path-wins.
|
|
34
20
|
#--
|
|
35
21
|
#: () -> Array[Riffer::Skills::Frontmatter]
|
|
36
22
|
def list_skills
|
|
@@ -59,12 +45,8 @@ class Riffer::Skills::FilesystemBackend < Riffer::Skills::Backend
|
|
|
59
45
|
frontmatters
|
|
60
46
|
end
|
|
61
47
|
|
|
62
|
-
# Returns the full SKILL.md body (without frontmatter) for a skill.
|
|
63
|
-
#
|
|
64
|
-
# [name] the skill name to read.
|
|
65
|
-
#
|
|
66
|
-
# Raises Riffer::ArgumentError if skill not found.
|
|
67
|
-
#
|
|
48
|
+
# Returns the full SKILL.md body (without frontmatter) for a skill. Raises
|
|
49
|
+
# Riffer::ArgumentError if the skill is not found.
|
|
68
50
|
#--
|
|
69
51
|
#: (String) -> String
|
|
70
52
|
def read_skill(name)
|
|
@@ -3,13 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
require "yaml"
|
|
5
5
|
|
|
6
|
-
# Immutable value object holding parsed SKILL.md YAML frontmatter.
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# All unrecognized top-level frontmatter keys are merged into +metadata+.
|
|
10
|
-
#
|
|
11
|
-
# frontmatter, body = Riffer::Skills::Frontmatter.parse(raw_content)
|
|
12
|
-
#
|
|
6
|
+
# Immutable value object holding parsed SKILL.md YAML frontmatter. Required
|
|
7
|
+
# fields: +name+ and +description+; unrecognized top-level keys are merged into
|
|
8
|
+
# +metadata+.
|
|
13
9
|
class Riffer::Skills::Frontmatter
|
|
14
10
|
NAME_PATTERN = /\A[a-z0-9]+(-[a-z0-9]+)*\z/ #: Regexp
|
|
15
11
|
MAX_NAME_LENGTH = 64 #: Integer
|
|
@@ -21,18 +17,13 @@ class Riffer::Skills::Frontmatter
|
|
|
21
17
|
# The skill description (1-1024 chars).
|
|
22
18
|
attr_reader :description #: String
|
|
23
19
|
|
|
24
|
-
#
|
|
25
|
-
#
|
|
20
|
+
# Metadata from the spec's +metadata+ field plus any unrecognized top-level
|
|
21
|
+
# keys.
|
|
26
22
|
attr_reader :metadata #: Hash[Symbol, untyped]
|
|
27
23
|
|
|
28
|
-
# Parses a raw SKILL.md string into a Frontmatter
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
# top-level keys become +metadata+. Available to custom backends
|
|
32
|
-
# so they don't need to reimplement parsing.
|
|
33
|
-
#
|
|
34
|
-
# Raises Riffer::ArgumentError if frontmatter is invalid.
|
|
35
|
-
#
|
|
24
|
+
# Parses a raw SKILL.md string into a +[Frontmatter, body]+ pair — public so
|
|
25
|
+
# custom backends needn't reimplement parsing. Raises Riffer::ArgumentError
|
|
26
|
+
# if the frontmatter is invalid.
|
|
36
27
|
#--
|
|
37
28
|
#: (String) -> [Riffer::Skills::Frontmatter, String]
|
|
38
29
|
def self.parse(raw)
|
|
@@ -42,9 +33,7 @@ class Riffer::Skills::Frontmatter
|
|
|
42
33
|
end
|
|
43
34
|
|
|
44
35
|
# Parses only the frontmatter from a raw SKILL.md string, ignoring the body.
|
|
45
|
-
#
|
|
46
|
-
# Raises Riffer::ArgumentError if frontmatter is invalid.
|
|
47
|
-
#
|
|
36
|
+
# Raises Riffer::ArgumentError if the frontmatter is invalid.
|
|
48
37
|
#--
|
|
49
38
|
#: (String) -> Riffer::Skills::Frontmatter
|
|
50
39
|
def self.parse_frontmatter(raw)
|
|
@@ -68,14 +57,7 @@ class Riffer::Skills::Frontmatter
|
|
|
68
57
|
end
|
|
69
58
|
private_class_method :split_frontmatter
|
|
70
59
|
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
# [name] the skill name (must match +[a-z0-9]([a-z0-9-]*[a-z0-9])?+, 1-64 chars).
|
|
74
|
-
# [description] the skill description (1-1024 chars).
|
|
75
|
-
# [metadata] optional metadata hash.
|
|
76
|
-
#
|
|
77
|
-
# Raises Riffer::ArgumentError if name or description is invalid.
|
|
78
|
-
#
|
|
60
|
+
# Raises Riffer::ArgumentError if +name+ or +description+ is invalid.
|
|
79
61
|
#--
|
|
80
62
|
#: (name: String, description: String, ?metadata: Hash[Symbol, untyped]) -> void
|
|
81
63
|
def initialize(name:, description:, metadata: {})
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Default
|
|
5
|
-
#
|
|
6
|
-
# Renders a skill catalog as Markdown for the system prompt.
|
|
7
|
-
# Used by OpenAI, Amazon Bedrock, and other providers.
|
|
8
|
-
#
|
|
9
|
-
# See Riffer::Skills::XmlAdapter for the Anthropic/Claude variant.
|
|
4
|
+
# Default skill adapter — renders a skill catalog as Markdown for the system
|
|
5
|
+
# prompt.
|
|
10
6
|
class Riffer::Skills::MarkdownAdapter < Riffer::Skills::Adapter
|
|
11
7
|
# Renders a skill catalog as Markdown.
|
|
12
|
-
#
|
|
13
|
-
# [skills] array of Frontmatter objects to render.
|
|
14
|
-
#
|
|
15
8
|
#--
|
|
16
9
|
#: (Array[Riffer::Skills::Frontmatter]) -> String
|
|
17
10
|
def render_catalog(skills)
|
|
@@ -3,16 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
require "cgi"
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# Renders a skill catalog as XML for the system prompt.
|
|
9
|
-
#
|
|
10
|
-
# See Riffer::Skills::MarkdownAdapter for the default variant.
|
|
6
|
+
# Renders a skill catalog as XML for the system prompt, optimized for
|
|
7
|
+
# Anthropic/Claude.
|
|
11
8
|
class Riffer::Skills::XmlAdapter < Riffer::Skills::Adapter
|
|
12
9
|
# Renders a skill catalog as XML.
|
|
13
|
-
#
|
|
14
|
-
# [skills] array of Frontmatter objects to render.
|
|
15
|
-
#
|
|
16
10
|
#--
|
|
17
11
|
#: (Array[Riffer::Skills::Frontmatter]) -> String
|
|
18
12
|
def render_catalog(skills)
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Base class for all streaming events
|
|
5
|
-
#
|
|
6
|
-
# Subclasses must implement the +to_h+ method.
|
|
4
|
+
# Base class for all streaming events. Subclasses must implement +to_h+.
|
|
7
5
|
class Riffer::StreamEvents::Base
|
|
8
6
|
# The message role (typically :assistant).
|
|
9
7
|
attr_reader :role #: Symbol
|
|
@@ -15,9 +13,6 @@ class Riffer::StreamEvents::Base
|
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
# Converts the event to a hash.
|
|
18
|
-
#
|
|
19
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
20
|
-
#
|
|
21
16
|
#--
|
|
22
17
|
#: () -> Hash[Symbol, untyped]
|
|
23
18
|
def to_h
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when a guardrail transforms data during the streaming pipeline.
|
|
4
|
+
# Emitted when a guardrail transforms data during streaming.
|
|
7
5
|
class Riffer::StreamEvents::GuardrailModification < Riffer::StreamEvents::Base
|
|
8
6
|
# The modification record.
|
|
9
7
|
attr_reader :modification #: Riffer::Guardrails::Modification
|
|
10
8
|
|
|
11
|
-
# Creates a new guardrail modification stream event.
|
|
12
|
-
#
|
|
13
|
-
# [modification] the modification details.
|
|
14
|
-
# [role] the message role (defaults to :assistant).
|
|
15
|
-
#
|
|
16
9
|
#--
|
|
17
10
|
#: (Riffer::Guardrails::Modification, ?role: Symbol) -> void
|
|
18
11
|
def initialize(modification, role: :assistant)
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when a guardrail blocks execution during the streaming pipeline.
|
|
4
|
+
# Emitted when a guardrail blocks execution during streaming.
|
|
7
5
|
class Riffer::StreamEvents::GuardrailTripwire < Riffer::StreamEvents::Base
|
|
8
6
|
# The tripwire containing block details.
|
|
9
7
|
attr_reader :tripwire #: Riffer::Guardrails::Tripwire
|
|
10
8
|
|
|
11
|
-
# Creates a new tripwire stream event.
|
|
12
|
-
#
|
|
13
|
-
# [tripwire] the tripwire details.
|
|
14
|
-
# [role] the message role (defaults to :assistant).
|
|
15
|
-
#
|
|
16
9
|
#--
|
|
17
10
|
#: (Riffer::Guardrails::Tripwire, ?role: Symbol) -> void
|
|
18
11
|
def initialize(tripwire, role: :assistant)
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents an interrupt
|
|
5
|
-
#
|
|
6
|
-
# Emitted when a callback interrupts the agent loop via +throw :riffer_interrupt+.
|
|
4
|
+
# Represents an interrupt during streaming, fired when a callback throws
|
|
5
|
+
# +:riffer_interrupt+.
|
|
7
6
|
class Riffer::StreamEvents::Interrupt < Riffer::StreamEvents::Base
|
|
8
7
|
# The reason provided with the interrupt, if any.
|
|
9
8
|
attr_reader :reason #: (String | Symbol)?
|
|
10
9
|
|
|
11
|
-
# Call ids of tool_use blocks
|
|
12
|
-
#
|
|
13
|
-
# +Riffer.config.experimental_history_healing+ is on.
|
|
10
|
+
# Call ids of tool_use blocks riffer filled with placeholder results when the
|
|
11
|
+
# interrupt fired (only when history healing is on).
|
|
14
12
|
attr_reader :healed_tool_call_ids #: Array[String]
|
|
15
13
|
|
|
16
14
|
#--
|
|
@@ -22,7 +20,6 @@ class Riffer::StreamEvents::Interrupt < Riffer::StreamEvents::Base
|
|
|
22
20
|
end
|
|
23
21
|
|
|
24
22
|
# Converts the event to a hash.
|
|
25
|
-
#
|
|
26
23
|
#--
|
|
27
24
|
#: () -> Hash[Symbol, untyped]
|
|
28
25
|
def to_h
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents an incremental reasoning chunk during streaming
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM produces reasoning/thinking content incrementally.
|
|
7
|
-
# Only available with providers that support reasoning (e.g., OpenAI with reasoning option).
|
|
4
|
+
# Represents an incremental reasoning chunk during streaming; only emitted by
|
|
5
|
+
# providers that support reasoning (e.g. OpenAI with the reasoning option).
|
|
8
6
|
class Riffer::StreamEvents::ReasoningDelta < Riffer::StreamEvents::Base
|
|
9
7
|
# The incremental reasoning content.
|
|
10
8
|
attr_reader :content #: String
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM has finished producing reasoning/thinking content.
|
|
7
|
-
# Only available with providers that support reasoning (e.g., OpenAI with reasoning option).
|
|
4
|
+
# Represents completed reasoning during streaming; only emitted by providers
|
|
5
|
+
# that support reasoning (e.g. OpenAI with the reasoning option).
|
|
8
6
|
class Riffer::StreamEvents::ReasoningDone < Riffer::StreamEvents::Base
|
|
9
7
|
# The complete reasoning content.
|
|
10
8
|
attr_reader :content #: String
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Emitted when a skill is activated during streaming
|
|
5
|
-
#
|
|
6
|
-
# Fired by the +on_activate+ callback on Riffer::Skills::Context
|
|
7
|
-
# when the LLM calls the skill activation tool.
|
|
4
|
+
# Emitted when a skill is activated during streaming, via the +on_activate+
|
|
5
|
+
# callback when the LLM calls the activation tool.
|
|
8
6
|
class Riffer::StreamEvents::SkillActivation < Riffer::StreamEvents::Base
|
|
9
7
|
# The activated skill name.
|
|
10
8
|
attr_reader :name #: String
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
# Represents an incremental text chunk during streaming.
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM produces text content incrementally.
|
|
7
5
|
class Riffer::StreamEvents::TextDelta < Riffer::StreamEvents::Base
|
|
8
6
|
# The incremental text content.
|
|
9
7
|
attr_reader :content #: String
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Represents
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM has finished producing text content.
|
|
4
|
+
# Represents completed text generation during streaming.
|
|
7
5
|
class Riffer::StreamEvents::TextDone < Riffer::StreamEvents::Base
|
|
8
6
|
# The complete text content.
|
|
9
7
|
attr_reader :content #: String
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM has finished and token usage data is available.
|
|
7
|
-
#
|
|
8
|
-
# event.token_usage.input_tokens # => 100
|
|
9
|
-
# event.token_usage.output_tokens # => 50
|
|
10
|
-
# event.token_usage.total_tokens # => 150
|
|
11
|
-
#
|
|
4
|
+
# Final token usage for the response, emitted when the LLM finishes.
|
|
12
5
|
class Riffer::StreamEvents::TokenUsageDone < Riffer::StreamEvents::Base
|
|
13
6
|
# The token usage data for this response.
|
|
14
7
|
attr_reader :token_usage #: Riffer::Providers::TokenUsage
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM is building a tool call, containing partial argument data.
|
|
4
|
+
# Represents an incremental tool call chunk (partial argument data) during
|
|
5
|
+
# streaming.
|
|
7
6
|
class Riffer::StreamEvents::ToolCallDelta < Riffer::StreamEvents::Base
|
|
8
7
|
# The tool call item identifier.
|
|
9
8
|
attr_reader :item_id #: String
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM has finished building a tool call with complete arguments.
|
|
4
|
+
# Represents a completed tool call during streaming.
|
|
7
5
|
class Riffer::StreamEvents::ToolCallDone < Riffer::StreamEvents::Base
|
|
8
6
|
# The tool call item identifier.
|
|
9
7
|
attr_reader :item_id #: String
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM has finished a server-side web search.
|
|
4
|
+
# The result of a completed server-side web search during streaming.
|
|
7
5
|
class Riffer::StreamEvents::WebSearchDone < Riffer::StreamEvents::Base
|
|
8
6
|
# The search query used.
|
|
9
7
|
attr_reader :query #: String
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# Emitted when the LLM performs a server-side web search and its status changes.
|
|
4
|
+
# A web search status notification, emitted as a server-side web search
|
|
5
|
+
# progresses.
|
|
7
6
|
class Riffer::StreamEvents::WebSearchStatus < Riffer::StreamEvents::Base
|
|
8
7
|
# The web search status ("in_progress", "searching", "completed", "open_page").
|
|
9
8
|
attr_reader :status #: String
|
data/lib/riffer/stream_events.rb
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Namespace for streaming event types in the Riffer framework.
|
|
5
|
-
#
|
|
6
|
-
# When streaming responses, these events are yielded to represent incremental updates:
|
|
7
|
-
# - Riffer::StreamEvents::TextDelta - Incremental text content
|
|
8
|
-
# - Riffer::StreamEvents::TextDone - Complete text content
|
|
9
|
-
# - Riffer::StreamEvents::ToolCallDelta - Incremental tool call arguments
|
|
10
|
-
# - Riffer::StreamEvents::ToolCallDone - Complete tool call
|
|
11
|
-
# - Riffer::StreamEvents::ReasoningDelta - Incremental reasoning content
|
|
12
|
-
# - Riffer::StreamEvents::ReasoningDone - Complete reasoning content
|
|
13
|
-
# - Riffer::StreamEvents::SkillActivation - Skill activated during streaming
|
|
14
4
|
module Riffer::StreamEvents
|
|
15
5
|
end
|
data/lib/riffer/tool.rb
CHANGED
|
@@ -3,12 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
require "timeout"
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# Provides a DSL for defining tool description and parameters.
|
|
9
|
-
# Subclasses must implement the +call+ method.
|
|
10
|
-
#
|
|
11
|
-
# See Riffer::Agent.
|
|
6
|
+
# Base class for all tools in the Riffer framework. Subclasses must implement
|
|
7
|
+
# the +call+ method.
|
|
12
8
|
#
|
|
13
9
|
# class WeatherLookupTool < Riffer::Tool
|
|
14
10
|
# description "Provides current weather information for a specified city."
|
|
@@ -29,16 +25,13 @@ class Riffer::Tool
|
|
|
29
25
|
kind :tool
|
|
30
26
|
|
|
31
27
|
# Executes the tool with the given arguments.
|
|
32
|
-
#
|
|
33
|
-
# Raises NotImplementedError if not implemented by subclass.
|
|
34
|
-
#
|
|
35
28
|
#--
|
|
36
29
|
#: (context: Riffer::Agent::Context?, **untyped) -> Riffer::Tools::Response
|
|
37
30
|
def call(context:, **kwargs)
|
|
38
31
|
raise NotImplementedError, "#{self.class} must implement #call"
|
|
39
32
|
end
|
|
40
33
|
|
|
41
|
-
# Creates a text response.
|
|
34
|
+
# Creates a text response.
|
|
42
35
|
#
|
|
43
36
|
#--
|
|
44
37
|
#: (untyped) -> Riffer::Tools::Response
|
|
@@ -46,7 +39,7 @@ class Riffer::Tool
|
|
|
46
39
|
Riffer::Tools::Response.text(result)
|
|
47
40
|
end
|
|
48
41
|
|
|
49
|
-
# Creates a JSON response.
|
|
42
|
+
# Creates a JSON response.
|
|
50
43
|
#
|
|
51
44
|
#--
|
|
52
45
|
#: (untyped) -> Riffer::Tools::Response
|
|
@@ -54,7 +47,7 @@ class Riffer::Tool
|
|
|
54
47
|
Riffer::Tools::Response.json(result)
|
|
55
48
|
end
|
|
56
49
|
|
|
57
|
-
# Creates an error response.
|
|
50
|
+
# Creates an error response.
|
|
58
51
|
#
|
|
59
52
|
#--
|
|
60
53
|
#: (String, ?type: Symbol) -> Riffer::Tools::Response
|
|
@@ -75,7 +68,7 @@ class Riffer::Tool
|
|
|
75
68
|
validated_args = params_builder ? params_builder.validate(kwargs) : kwargs
|
|
76
69
|
|
|
77
70
|
result = Timeout.timeout(self.class.timeout) do
|
|
78
|
-
call(context: context, **validated_args)
|
|
71
|
+
call(context: context, **validated_args) #: untyped
|
|
79
72
|
end
|
|
80
73
|
|
|
81
74
|
unless result.is_a?(Riffer::Tools::Response)
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
# All tools must return a Response object from their +call+ method.
|
|
9
|
-
# Use +Response.success+ for successful results and +Response.error+ for failures.
|
|
6
|
+
# Represents the result of a tool execution; every tool's +call+ must return one.
|
|
10
7
|
#
|
|
11
8
|
# class MyTool < Riffer::Tool
|
|
12
9
|
# def call(context:, **kwargs)
|
|
@@ -22,8 +19,13 @@ class Riffer::Tools::Response
|
|
|
22
19
|
|
|
23
20
|
VALID_FORMATS = %i[text json].freeze #: Array[Symbol]
|
|
24
21
|
|
|
22
|
+
# The response content.
|
|
25
23
|
attr_reader :content #: String
|
|
24
|
+
|
|
25
|
+
# The error message, or +nil+ on success.
|
|
26
26
|
attr_reader :error_message #: String?
|
|
27
|
+
|
|
28
|
+
# The error type, or +nil+ on success.
|
|
27
29
|
attr_reader :error_type #: Symbol?
|
|
28
30
|
|
|
29
31
|
# Creates a success response.
|
|
@@ -65,10 +67,12 @@ class Riffer::Tools::Response
|
|
|
65
67
|
new(content: message, success: false, error_message: message, error_type: type)
|
|
66
68
|
end
|
|
67
69
|
|
|
70
|
+
# Returns true if the tool execution succeeded.
|
|
68
71
|
#--
|
|
69
72
|
#: () -> bool
|
|
70
73
|
def success? = @success
|
|
71
74
|
|
|
75
|
+
# Returns true if the tool execution failed.
|
|
72
76
|
#--
|
|
73
77
|
#: () -> bool
|
|
74
78
|
def error? = !@success
|
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
# end
|
|
9
9
|
#
|
|
10
10
|
class Riffer::Tools::Runtime::Fibers < Riffer::Tools::Runtime
|
|
11
|
-
# [max_concurrency] maximum number of tool calls to execute simultaneously.
|
|
12
|
-
# When +nil+, all tool calls run as fibers without limit.
|
|
13
|
-
#
|
|
14
11
|
#--
|
|
15
12
|
#: (?max_concurrency: Integer?) -> void
|
|
16
13
|
def initialize(max_concurrency: nil)
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
|
-
# Executes tool calls sequentially in the current thread.
|
|
5
|
-
#
|
|
6
|
-
# This is the default tool runtime used when no runtime is configured.
|
|
7
|
-
#
|
|
4
|
+
# Executes tool calls sequentially in the current thread — the default runtime.
|
|
8
5
|
class Riffer::Tools::Runtime::Inline < Riffer::Tools::Runtime
|
|
9
6
|
#--
|
|
10
7
|
#: () -> void
|
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
class Riffer::Tools::Runtime::Threaded < Riffer::Tools::Runtime
|
|
11
11
|
DEFAULT_MAX_CONCURRENCY = 5 #: Integer
|
|
12
12
|
|
|
13
|
-
# [max_concurrency] maximum number of tool calls to execute simultaneously.
|
|
14
|
-
#
|
|
15
13
|
#--
|
|
16
14
|
#: (?max_concurrency: Integer) -> void
|
|
17
15
|
def initialize(max_concurrency: DEFAULT_MAX_CONCURRENCY)
|
data/lib/riffer/tools/runtime.rb
CHANGED
|
@@ -3,25 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
# +execute+ as the sole public entry point.
|
|
10
|
-
#
|
|
11
|
-
# Subclass and override +dispatch_tool_call+ to customize how individual
|
|
12
|
-
# tool calls are dispatched (e.g., HTTP, gRPC).
|
|
13
|
-
#
|
|
14
|
-
# runtime = Riffer::Tools::Runtime::Inline.new
|
|
15
|
-
# results = runtime.execute(tool_calls, tools: tools, context: context)
|
|
16
|
-
#
|
|
6
|
+
# Handles tool call execution for an agent, composing with a Riffer::Runner for
|
|
7
|
+
# concurrency. Subclass and override +dispatch_tool_call+ to customize dispatch
|
|
8
|
+
# (e.g. HTTP, gRPC).
|
|
17
9
|
class Riffer::Tools::Runtime
|
|
18
10
|
# @rbs @runner: Riffer::Runner
|
|
19
11
|
|
|
20
|
-
# [runner] the concurrency runner to use for batch execution.
|
|
21
|
-
#
|
|
22
|
-
# Subclasses must provide a runner; instantiating Riffer::Tools::Runtime directly
|
|
23
|
-
# raises +NotImplementedError+.
|
|
24
|
-
#
|
|
25
12
|
#--
|
|
26
13
|
#: (runner: Riffer::Runner) -> void
|
|
27
14
|
def initialize(runner:)
|
|
@@ -30,15 +17,6 @@ class Riffer::Tools::Runtime
|
|
|
30
17
|
end
|
|
31
18
|
|
|
32
19
|
# Executes a batch of tool calls, returning <tt>[tool_call, response]</tt> pairs.
|
|
33
|
-
#
|
|
34
|
-
# [tool_calls] the tool calls to execute.
|
|
35
|
-
# [tools] the resolved tool classes.
|
|
36
|
-
# [context] the context hash.
|
|
37
|
-
# [assistant_message] the assistant message that produced these tool
|
|
38
|
-
# calls, when known. Forwarded to +around_tool_call+ and
|
|
39
|
-
# +dispatch_tool_call+ so subclasses can access it (e.g. for
|
|
40
|
-
# instrumentation that needs the accompanying assistant text).
|
|
41
|
-
#
|
|
42
20
|
#--
|
|
43
21
|
#: (Array[Riffer::Messages::Assistant::ToolCall], tools: Array[singleton(Riffer::Tool)], context: Riffer::Agent::Context?, ?assistant_message: Riffer::Messages::Assistant?) -> Array[[Riffer::Messages::Assistant::ToolCall, Riffer::Tools::Response]]
|
|
44
22
|
def execute(tool_calls, tools:, context:, assistant_message: nil)
|
|
@@ -50,10 +28,8 @@ class Riffer::Tools::Runtime
|
|
|
50
28
|
end
|
|
51
29
|
end
|
|
52
30
|
|
|
53
|
-
# Hook
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
# The default implementation simply yields.
|
|
31
|
+
# Hook wrapping each tool call; override in subclasses to instrument or
|
|
32
|
+
# customize. Must +yield+ to continue.
|
|
57
33
|
#
|
|
58
34
|
# class InstrumentedRuntime < Riffer::Tools::Runtime::Inline
|
|
59
35
|
# private
|
|
@@ -74,15 +50,6 @@ class Riffer::Tools::Runtime
|
|
|
74
50
|
|
|
75
51
|
private
|
|
76
52
|
|
|
77
|
-
# Dispatches a single tool call. Override in subclasses to change
|
|
78
|
-
# how individual tools are invoked (e.g., HTTP, gRPC).
|
|
79
|
-
#
|
|
80
|
-
# [tool_call] the tool call to execute.
|
|
81
|
-
# [tools] the resolved tool classes.
|
|
82
|
-
# [context] the context hash.
|
|
83
|
-
# [assistant_message] the assistant message that produced this tool
|
|
84
|
-
# call, when known.
|
|
85
|
-
#
|
|
86
53
|
#--
|
|
87
54
|
#: (Riffer::Messages::Assistant::ToolCall, tools: Array[singleton(Riffer::Tool)], context: Riffer::Agent::Context?, ?assistant_message: Riffer::Messages::Assistant?) -> Riffer::Tools::Response
|
|
88
55
|
def dispatch_tool_call(tool_call, tools:, context:, assistant_message: nil)
|