riffer 0.39.0 → 0.41.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/architecture.md +2 -2
- data/.agents/code-style.md +4 -3
- data/.agents/providers.md +12 -3
- data/.agents/rbs-inline.md +2 -2
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +112 -0
- data/AGENTS.md +6 -6
- data/CHANGELOG.md +18 -0
- data/README.md +35 -37
- data/Rakefile +26 -6
- data/Steepfile +2 -0
- data/docs/{03_AGENTS.md → AGENTS.md} +12 -23
- data/docs/{04_AGENT_LIFECYCLE.md → AGENT_LIFECYCLE.md} +1 -1
- data/docs/{10_CONFIGURATION.md → CONFIGURATION.md} +115 -31
- data/docs/{02_GETTING_STARTED.md → GETTING_STARTED.md} +6 -6
- data/docs/{14_MCP.md → MCP.md} +1 -1
- data/docs/{08_MESSAGES.md → MESSAGES.md} +4 -4
- data/docs/{01_OVERVIEW.md → OVERVIEW.md} +15 -15
- data/docs/{15_SERIALIZATION.md → SERIALIZATION.md} +8 -7
- data/docs/{09_STREAM_EVENTS.md → STREAM_EVENTS.md} +4 -4
- data/docs/{06_TOOLS.md → TOOLS.md} +1 -1
- data/docs/{16_TRACING.md → TRACING.md} +6 -6
- data/docs/providers/{02_AMAZON_BEDROCK.md → AMAZON_BEDROCK.md} +14 -8
- data/docs/providers/{03_ANTHROPIC.md → ANTHROPIC.md} +9 -7
- data/docs/providers/{05_AZURE_OPENAI.md → AZURE_OPENAI.md} +12 -12
- data/docs/providers/{07_CUSTOM_PROVIDERS.md → CUSTOM_PROVIDERS.md} +34 -18
- data/docs/providers/{08_GEMINI.md → GEMINI.md} +28 -5
- data/docs/providers/{04_OPENAI.md → OPENAI.md} +21 -5
- data/docs/providers/{09_OPENROUTER.md → OPENROUTER.md} +11 -6
- data/docs/providers/{01_PROVIDERS.md → PROVIDERS.md} +24 -9
- data/docs-site/404.html +51 -0
- data/docs-site/build.rb +144 -0
- data/docs-site/check.rb +64 -0
- data/docs-site/copy.js +20 -0
- data/docs-site/favicon.svg +18 -0
- data/docs-site/index.html.erb +194 -0
- data/docs-site/landing.css +315 -0
- data/docs-site/layout.html.erb +101 -0
- data/docs-site/manifest.yml +96 -0
- data/docs-site/site.css +598 -0
- data/lib/riffer/agent/config.rb +33 -14
- data/lib/riffer/agent/context.rb +6 -6
- data/lib/riffer/agent/response.rb +24 -2
- data/lib/riffer/agent/run.rb +121 -30
- data/lib/riffer/agent/serializer.rb +17 -10
- data/lib/riffer/agent/session/repair.rb +12 -11
- data/lib/riffer/agent/session.rb +16 -15
- data/lib/riffer/agent.rb +50 -20
- data/lib/riffer/config.rb +41 -18
- data/lib/riffer/evals/evaluator.rb +10 -3
- data/lib/riffer/evals/evaluator_runner.rb +3 -2
- data/lib/riffer/evals/judge.rb +7 -8
- data/lib/riffer/evals/result.rb +1 -1
- data/lib/riffer/evals/run_result.rb +3 -3
- data/lib/riffer/evals/scenario_result.rb +2 -2
- data/lib/riffer/guardrails/modification.rb +1 -1
- data/lib/riffer/guardrails/runner.rb +14 -9
- data/lib/riffer/guardrails/tripwire.rb +1 -1
- data/lib/riffer/helpers/boolean.rb +1 -1
- data/lib/riffer/helpers/call_or_value.rb +1 -0
- data/lib/riffer/helpers/class_name_converter.rb +6 -6
- data/lib/riffer/mcp/authenticated_tool.rb +2 -4
- data/lib/riffer/mcp/client.rb +2 -4
- data/lib/riffer/mcp/registry.rb +6 -2
- data/lib/riffer/mcp/search_tool.rb +1 -1
- data/lib/riffer/mcp/tool_factory.rb +5 -5
- data/lib/riffer/mcp.rb +1 -1
- data/lib/riffer/messages/assistant.rb +4 -3
- data/lib/riffer/messages/base.rb +13 -11
- data/lib/riffer/messages/file_part.rb +7 -6
- data/lib/riffer/messages/tool.rb +2 -2
- data/lib/riffer/messages/user.rb +2 -2
- data/lib/riffer/params/param.rb +8 -8
- data/lib/riffer/params.rb +31 -31
- data/lib/riffer/providers/amazon_bedrock.rb +79 -62
- data/lib/riffer/providers/anthropic.rb +82 -61
- data/lib/riffer/providers/azure_open_ai.rb +18 -16
- data/lib/riffer/providers/base.rb +68 -21
- data/lib/riffer/providers/gemini/client.rb +120 -0
- data/lib/riffer/providers/gemini.rb +47 -93
- data/lib/riffer/providers/mock.rb +27 -14
- data/lib/riffer/providers/open_ai.rb +62 -39
- data/lib/riffer/providers/open_router.rb +54 -41
- data/lib/riffer/providers/repository.rb +1 -1
- data/lib/riffer/providers/token_usage.rb +10 -8
- data/lib/riffer/runner/fibers.rb +7 -6
- data/lib/riffer/runner/sequential.rb +2 -2
- data/lib/riffer/runner/threaded.rb +4 -3
- data/lib/riffer/skills/adapter.rb +4 -2
- data/lib/riffer/skills/config.rb +7 -1
- data/lib/riffer/skills/context.rb +5 -1
- data/lib/riffer/skills/filesystem_backend.rb +2 -0
- data/lib/riffer/skills/frontmatter.rb +27 -5
- data/lib/riffer/stream_events/finish_reason_done.rb +3 -2
- data/lib/riffer/stream_events/guardrail_modification.rb +1 -1
- data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -1
- data/lib/riffer/stream_events/interrupt.rb +1 -1
- data/lib/riffer/stream_events/reasoning_delta.rb +1 -1
- data/lib/riffer/stream_events/reasoning_done.rb +1 -1
- data/lib/riffer/stream_events/skill_activation.rb +1 -1
- data/lib/riffer/stream_events/text_delta.rb +1 -1
- data/lib/riffer/stream_events/text_done.rb +1 -1
- data/lib/riffer/stream_events/token_usage_done.rb +1 -1
- data/lib/riffer/stream_events/tool_call_delta.rb +1 -1
- data/lib/riffer/stream_events/tool_call_done.rb +1 -1
- data/lib/riffer/stream_events/web_search_done.rb +1 -1
- data/lib/riffer/stream_events/web_search_status.rb +1 -1
- data/lib/riffer/tools/response.rb +3 -3
- data/lib/riffer/tools/runtime.rb +15 -7
- data/lib/riffer/tools/toolable.rb +17 -5
- data/lib/riffer/tracing/capture.rb +7 -7
- data/lib/riffer/tracing/no_op.rb +4 -8
- data/lib/riffer/tracing/otel.rb +8 -4
- data/lib/riffer/tracing/stream_recorder.rb +5 -1
- data/lib/riffer/tracing.rb +9 -6
- data/lib/riffer/version.rb +1 -1
- data/lib/riffer.rb +2 -2
- data/sig/_private/riffer/providers/amazon_bedrock.rbs +4 -2
- data/sig/_private/riffer/providers/anthropic.rbs +4 -2
- data/sig/_private/riffer/providers/gemini.rbs +7 -0
- data/sig/_private/riffer/providers/open_ai.rbs +4 -2
- data/sig/_private/riffer/providers/open_router.rbs +4 -2
- data/sig/generated/riffer/agent/config.rbs +14 -5
- data/sig/generated/riffer/agent/response.rbs +12 -1
- data/sig/generated/riffer/agent/run.rbs +12 -1
- data/sig/generated/riffer/agent.rbs +1 -7
- data/sig/generated/riffer/config.rbs +25 -15
- data/sig/generated/riffer/evals/judge.rbs +2 -4
- data/sig/generated/riffer/mcp.rbs +1 -1
- data/sig/generated/riffer/providers/amazon_bedrock.rbs +13 -2
- data/sig/generated/riffer/providers/anthropic.rbs +13 -2
- data/sig/generated/riffer/providers/azure_open_ai.rbs +14 -4
- data/sig/generated/riffer/providers/base.rbs +20 -0
- data/sig/generated/riffer/providers/gemini/client.rbs +65 -0
- data/sig/generated/riffer/providers/gemini.rbs +7 -23
- data/sig/generated/riffer/providers/mock.rbs +6 -4
- data/sig/generated/riffer/providers/open_ai.rbs +13 -2
- data/sig/generated/riffer/providers/open_router.rbs +16 -3
- metadata +41 -229
- data/.standard.yml +0 -1
- /data/docs/{05_AGENT_LOOP.md → AGENT_LOOP.md} +0 -0
- /data/docs/{11_EVALS.md → EVALS.md} +0 -0
- /data/docs/{12_GUARDRAILS.md → GUARDRAILS.md} +0 -0
- /data/docs/{13_SKILLS.md → SKILLS.md} +0 -0
- /data/docs/{07_TOOL_ADVANCED.md → TOOL_ADVANCED.md} +0 -0
- /data/docs/providers/{06_MOCK_PROVIDER.md → MOCK_PROVIDER.md} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd309de6be56bd5fbe778bbf277b9125dd63d4ce7b360c3e5e85554a944cb81d
|
|
4
|
+
data.tar.gz: 965daf888849a0386b2826af572fd95d0a7fb8a4ac6f9f91788acb0254705f8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: deedbd28b2c79faceea167422fb69147cb2453d7e06df48c46c2eb1e601068de7b9018026675a973f6de6036373d324d5120fc43269e863dd43ce39b88ee7ea4
|
|
7
|
+
data.tar.gz: 2007cc98bd5955ae2db4776e72551d546038deea60be3e397a5838e028cd2901465f2fe9c00d944b18e4ce9508599bcd7603ad61e0e75efaa8264793461cf283
|
data/.agents/architecture.md
CHANGED
|
@@ -136,7 +136,7 @@ Context flow: `Agent#execute_tool_calls` → `Tools::Runtime#execute(tool_calls,
|
|
|
136
136
|
|
|
137
137
|
### MCP Integration (`lib/riffer/mcp/`)
|
|
138
138
|
|
|
139
|
-
Register third-party MCP servers globally; agents opt-in by tag via `use_mcp`. Tags are application-defined (manifests may list several; any overlap with `use_mcp` opts in—see `docs/
|
|
139
|
+
Register third-party MCP servers globally; agents opt-in by tag via `use_mcp`. Tags are application-defined (manifests may list several; any overlap with `use_mcp` opts in—see `docs/MCP.md`).
|
|
140
140
|
|
|
141
141
|
```ruby
|
|
142
142
|
Riffer::Mcp.register(
|
|
@@ -146,7 +146,7 @@ Riffer::Mcp.register(
|
|
|
146
146
|
discovery_headers: -> { {"Authorization" => "Bearer #{ENV['GITHUB_TOKEN']}"} }
|
|
147
147
|
)
|
|
148
148
|
|
|
149
|
-
# Optional: per-run tools/call headers (see docs/
|
|
149
|
+
# Optional: per-run tools/call headers (see docs/MCP.md)
|
|
150
150
|
Riffer.configure { |c| c.mcp.credentials = ->(manifest:, matched_tags:, context:) { ... } }
|
|
151
151
|
|
|
152
152
|
class ResearchAgent < Riffer::Agent
|
data/.agents/code-style.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Formatting
|
|
4
4
|
|
|
5
|
-
- Use
|
|
6
|
-
-
|
|
7
|
-
- Run `bin/lint` to check, `bin/lint
|
|
5
|
+
- Use RuboCop for linting and formatting
|
|
6
|
+
- Config lives in `.rubocop.yml`, with cops sorted alphabetically
|
|
7
|
+
- Run `bin/lint` to check, `bin/lint -a` to auto-fix (safe autocorrect), `bin/lint -A` for unsafe autocorrect
|
|
8
|
+
- Never silence violations with inline `rubocop:disable` comments — fix them, or when an exception is genuinely warranted add a narrowly scoped override in `.rubocop.yml` with a comment explaining why
|
|
8
9
|
|
|
9
10
|
## Required Header
|
|
10
11
|
|
data/.agents/providers.md
CHANGED
|
@@ -3,11 +3,20 @@
|
|
|
3
3
|
## Steps
|
|
4
4
|
|
|
5
5
|
1. Create `lib/riffer/providers/your_provider.rb` extending `Riffer::Providers::Base`
|
|
6
|
-
2. Implement the required hook methods (see [Custom Providers](../docs/providers/
|
|
6
|
+
2. Implement the required hook methods (see [Custom Providers](../docs/providers/CUSTOM_PROVIDERS.md) for the full API)
|
|
7
7
|
3. Register in `Riffer::Providers::Repository::REPO`
|
|
8
|
-
4. Add provider config to `Riffer::Config` if needed
|
|
8
|
+
4. Add provider config to `Riffer::Config` if needed — a `Struct` with credential members plus a `client` member
|
|
9
9
|
5. Create tests in `test/riffer/providers/your_provider_test.rb`
|
|
10
10
|
|
|
11
|
+
## Constructor and client contract
|
|
12
|
+
|
|
13
|
+
- Constructors take **no arguments** — define one only when the provider needs `depends_on`, and give it no parameters. Credentials live in config; never accept them as kwargs or hold them in ivars.
|
|
14
|
+
- Never hold a client ivar; call the private `client` method from `execute_generate`/`execute_stream`. Base resolves: `global_client` (a client instance, or a no-argument Proc resolved on every call) → memoized `build_client`.
|
|
15
|
+
- Providers hold no agent state — no context, no reference to the owning agent. Client selection is process-global by design, so a configured Proc takes no arguments.
|
|
16
|
+
- Implement `build_client` (build the SDK client by reading `Riffer.config.<provider>.<credential>` directly) and override `global_client` to return `Riffer.config.<provider>.client`.
|
|
17
|
+
- **Never pass an SDK an explicit nil credential.** Build the kwargs as a hash and `.compact` it, so an unset value stays _absent_: SDKs distinguish absent from nil to decide whether to read their own env vars, and an explicit nil suppresses that. Passing `base_url: nil` skips `OPENAI_BASE_URL` and pins requests to api.openai.com; passing `region: nil` makes the AWS SDK raise `MissingRegionError` even with `AWS_REGION` exported.
|
|
18
|
+
- **Exception — a provider borrowing another vendor's SDK** (`OpenRouter` and `AzureOpenAI` reuse `::OpenAI::Client`) must keep its credential and endpoint concrete, nil included. Compacting there would let the OpenAI SDK fall back to `OPENAI_API_KEY` / `OPENAI_BASE_URL` and send one vendor's credential to another's endpoint. Compact a key only when the SDK's env fallback for it names the same service the provider talks to.
|
|
19
|
+
|
|
11
20
|
## Architecture
|
|
12
21
|
|
|
13
22
|
The base class uses the **template method** pattern. The public methods `generate_text` and `stream_text` orchestrate the flow, delegating to hook methods that each provider implements:
|
|
@@ -42,4 +51,4 @@ Use `depends_on` helper for runtime dependency checking if your provider require
|
|
|
42
51
|
|
|
43
52
|
## Reference
|
|
44
53
|
|
|
45
|
-
For hook method signatures, structured output handling, file handling, and complete examples, see [Custom Providers](../docs/providers/
|
|
54
|
+
For hook method signatures, structured output handling, file handling, and complete examples, see [Custom Providers](../docs/providers/CUSTOM_PROVIDERS.md).
|
data/.agents/rbs-inline.md
CHANGED
|
@@ -154,8 +154,8 @@ end
|
|
|
154
154
|
|
|
155
155
|
### Where stubs and stdlib deps live
|
|
156
156
|
|
|
157
|
-
- `sig/_private/` — signatures that must **not** ship. RBS **skips** `_`-prefixed directories in library mode, so consumers never load them; riffer's own `steep check` does (via the `Steepfile`). Two kinds, by predictable path: external-gem signatures are named by gem at the top level (`async.rbs`, `mcp.rbs`, `zeitwerk.rbs`, `openai.rbs`, `anthropic.rbs`, `aws-sdk-core/*` — full stubs for RBS-less gems plus arity patches for the provider SDKs); riffer's own hidden stubs mirror `lib/` under `riffer/` (e.g. `riffer/providers/anthropic.rbs`
|
|
158
|
-
- `sig/manual/` — hand-written riffer-only signatures that are **safe to ship**, for the few things rbs-inline can't generate _at all_ (mirroring `lib/`). In practice that's `extend self` modules (`riffer/agent/run.rbs`, `riffer/helpers/call_or_value.rbs`) and modeling an include applied dynamically (`riffer/tools/toolable.rbs`). SDK-free ivars are **not** hand-written here — declare them inline with `# @rbs` (see "Instance variables"). SDK-typed
|
|
157
|
+
- `sig/_private/` — signatures that must **not** ship. RBS **skips** `_`-prefixed directories in library mode, so consumers never load them; riffer's own `steep check` does (via the `Steepfile`). Two kinds, by predictable path: external-gem signatures are named by gem at the top level (`async.rbs`, `mcp.rbs`, `zeitwerk.rbs`, `openai.rbs`, `anthropic.rbs`, `aws-sdk-core/*` — full stubs for RBS-less gems plus arity patches for the provider SDKs); riffer's own hidden stubs mirror `lib/` under `riffer/` (e.g. `riffer/providers/anthropic.rbs` narrows the private `client` method to the SDK-typed client).
|
|
158
|
+
- `sig/manual/` — hand-written riffer-only signatures that are **safe to ship**, for the few things rbs-inline can't generate _at all_ (mirroring `lib/`). In practice that's `extend self` modules (`riffer/agent/run.rbs`, `riffer/helpers/call_or_value.rbs`) and modeling an include applied dynamically (`riffer/tools/toolable.rbs`). SDK-free ivars are **not** hand-written here — declare them inline with `# @rbs` (see "Instance variables"). SDK-typed signatures can't ship, so they go in `_private/riffer/providers/` (the narrowed `client`).
|
|
159
159
|
- `sig/manifest.yaml` — declares the **stdlib** RBS the shipped sigs reference (`uri`, `net-http`) so `rbs -r riffer` resolves them.
|
|
160
160
|
|
|
161
161
|
## Workflow
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-minitest
|
|
3
|
+
- rubocop-performance
|
|
4
|
+
- rubocop-rake
|
|
5
|
+
|
|
6
|
+
# ── Tier 1: house style — settings changed from RuboCop defaults everywhere ──
|
|
7
|
+
|
|
8
|
+
Layout/BlockAlignment:
|
|
9
|
+
EnforcedStyleAlignWith: start_of_block
|
|
10
|
+
|
|
11
|
+
Layout/DotPosition:
|
|
12
|
+
EnforcedStyle: trailing
|
|
13
|
+
|
|
14
|
+
Layout/MultilineMethodCallIndentation:
|
|
15
|
+
EnforcedStyle: indented
|
|
16
|
+
|
|
17
|
+
Style/HashSyntax:
|
|
18
|
+
EnforcedShorthandSyntax: either_consistent
|
|
19
|
+
|
|
20
|
+
Style/NonNilCheck:
|
|
21
|
+
IncludeSemanticChanges: true
|
|
22
|
+
|
|
23
|
+
Style/StringLiterals:
|
|
24
|
+
EnforcedStyle: double_quotes
|
|
25
|
+
|
|
26
|
+
Style/TrailingCommaInArguments:
|
|
27
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
28
|
+
|
|
29
|
+
Style/TrailingCommaInArrayLiteral:
|
|
30
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
31
|
+
|
|
32
|
+
Style/TrailingCommaInHashLiteral:
|
|
33
|
+
EnforcedStyleForMultiline: consistent_comma
|
|
34
|
+
|
|
35
|
+
# ── Tier 2: shared base — additions and deviations from the house style ──
|
|
36
|
+
|
|
37
|
+
AllCops:
|
|
38
|
+
DisabledByDefault: false
|
|
39
|
+
# Stricter than the house style, which leaves pending cops as warnings;
|
|
40
|
+
# enabling adopts new cops automatically and kills the warning spam.
|
|
41
|
+
NewCops: enable
|
|
42
|
+
SuggestExtensions: false
|
|
43
|
+
|
|
44
|
+
# Size thresholds are noise; BlockNesting stays — deep nesting is the one
|
|
45
|
+
# limit worth enforcing.
|
|
46
|
+
Metrics:
|
|
47
|
+
Enabled: false
|
|
48
|
+
|
|
49
|
+
Metrics/BlockNesting:
|
|
50
|
+
Enabled: true
|
|
51
|
+
|
|
52
|
+
# A comment on every class is a "what" — conflicts with the comments rule.
|
|
53
|
+
Style/Documentation:
|
|
54
|
+
Enabled: false
|
|
55
|
+
|
|
56
|
+
# The function-module pattern needs a working `private`.
|
|
57
|
+
Style/ModuleFunction:
|
|
58
|
+
EnforcedStyle: extend_self
|
|
59
|
+
|
|
60
|
+
# Compact (`class Foo::Bar`) cuts LOC and nesting and ends the nested/compact
|
|
61
|
+
# mix across codebases.
|
|
62
|
+
Style/ClassAndModuleChildren:
|
|
63
|
+
EnforcedStyle: compact
|
|
64
|
+
|
|
65
|
+
# Keyword arguments often stay unused to keep signatures uniform across
|
|
66
|
+
# interchangeable implementations.
|
|
67
|
+
Lint/UnusedMethodArgument:
|
|
68
|
+
AllowUnusedKeywordArguments: true
|
|
69
|
+
|
|
70
|
+
# Additions, not overrides: RBS-inline annotations must lint.
|
|
71
|
+
Layout/LeadingCommentSpace:
|
|
72
|
+
AllowRBSInlineAnnotation: true
|
|
73
|
+
|
|
74
|
+
Layout/LineLength:
|
|
75
|
+
AllowedPatterns: ['#:']
|
|
76
|
+
|
|
77
|
+
Minitest/MultipleAssertions:
|
|
78
|
+
Max: 3
|
|
79
|
+
|
|
80
|
+
# ── Tier 3: riffer deviations, each with its reason ──
|
|
81
|
+
|
|
82
|
+
# Tests use deliberately empty blocks: `.each { |_| }` to drain a stream for
|
|
83
|
+
# its side effects, empty `in_span` bodies to assert span lifecycle, and no-op
|
|
84
|
+
# stream doubles.
|
|
85
|
+
Lint/EmptyBlock:
|
|
86
|
+
Exclude:
|
|
87
|
+
- test/**/*
|
|
88
|
+
|
|
89
|
+
# Keyword-argument names are the calling contract for riffer's block-based
|
|
90
|
+
# hooks (tool `execute` blocks, evaluator lambdas, dynamic instructions) —
|
|
91
|
+
# underscore-prefixing a block keyword renames the keyword and breaks callers.
|
|
92
|
+
Lint/UnusedBlockArgument:
|
|
93
|
+
AllowUnusedKeywordArguments: true
|
|
94
|
+
|
|
95
|
+
# validate_as_tool! follows the validate!/save! idiom: raise or return true.
|
|
96
|
+
# Its return value is not a predicate.
|
|
97
|
+
Naming/PredicateMethod:
|
|
98
|
+
AllowBangMethods: true
|
|
99
|
+
|
|
100
|
+
# has_tool_calls? is shipped public API — renaming it breaks consumers.
|
|
101
|
+
Naming/PredicatePrefix:
|
|
102
|
+
AllowedMethods:
|
|
103
|
+
- has_tool_calls?
|
|
104
|
+
|
|
105
|
+
# Riffer::Messages::Base#+ and Riffer::Providers::TokenUsage#+ merge objects;
|
|
106
|
+
# the cop's `sum` rewrite starts the fold from 0 and raises on non-numeric
|
|
107
|
+
# elements.
|
|
108
|
+
Performance/Sum:
|
|
109
|
+
Exclude:
|
|
110
|
+
- lib/riffer/providers/base.rb
|
|
111
|
+
- lib/riffer/evals/run_result.rb
|
|
112
|
+
- lib/riffer/evals/scenario_result.rb
|
data/AGENTS.md
CHANGED
|
@@ -5,16 +5,16 @@ Ruby gem framework for building AI-powered agents with LLM provider adapters.
|
|
|
5
5
|
## Quick Reference
|
|
6
6
|
|
|
7
7
|
- **Ruby**: 3.3.0+ (CI: 3.3, 3.4, 4.0)
|
|
8
|
-
- **Lint + Test**: `bin/rake` (runs the default task: test +
|
|
8
|
+
- **Lint + Test**: `bin/rake` (runs the default task: test + rubocop + steep:check)
|
|
9
9
|
- **Autoloading**: Zeitwerk (file paths must match module/class names)
|
|
10
10
|
- **Model format**: `provider/model` (e.g., `openai/gpt-4`)
|
|
11
|
-
- **Docs**: when adding a public config option or message attribute, update the matching page in `docs/` (e.g., `docs/
|
|
11
|
+
- **Docs**: when adding a public config option or message attribute, update the matching page in `docs/` (e.g., `docs/CONFIGURATION.md`, `docs/MESSAGES.md`). Adding a NEW page under `docs/` also requires a `docs-site/manifest.yml` entry — the site build fails without one. RDoc ≠ user docs.
|
|
12
12
|
|
|
13
13
|
## Topic Guides
|
|
14
14
|
|
|
15
15
|
- [Architecture](.agents/architecture.md) - Core components and project structure
|
|
16
16
|
- [Testing](.agents/testing.md) - Minitest spec DSL and VCR cassettes
|
|
17
|
-
- [Code Style](.agents/code-style.md) -
|
|
17
|
+
- [Code Style](.agents/code-style.md) - RuboCop, comment, and RDoc conventions
|
|
18
18
|
- [Providers](.agents/providers.md) - Adding new LLM provider adapters
|
|
19
19
|
- [RBS Inline](.agents/rbs-inline.md) - Type annotations with rbs-inline
|
|
20
20
|
|
|
@@ -24,13 +24,13 @@ All wrappers `exec bundle exec …` under the hood.
|
|
|
24
24
|
|
|
25
25
|
| Command | Description |
|
|
26
26
|
| --------------- | -------------------------------------------- |
|
|
27
|
-
| `bin/rake` | Default task: test +
|
|
27
|
+
| `bin/rake` | Default task: test + rubocop + steep:check |
|
|
28
28
|
| `bin/test` | Run tests |
|
|
29
|
-
| `bin/lint` | Check code style (pass
|
|
29
|
+
| `bin/lint` | Check code style (pass `-a` to auto-fix) |
|
|
30
30
|
| `bin/typecheck` | Run Steep type checker |
|
|
31
31
|
| `bin/rbs` | Generate RBS type signatures |
|
|
32
32
|
| `bin/rbs-watch` | Watch and regenerate RBS files |
|
|
33
|
-
| `bin/docs` | Build
|
|
33
|
+
| `bin/docs` | Build the docs site + API reference |
|
|
34
34
|
| `bin/build` | Build the gem package |
|
|
35
35
|
| `bin/console` | Interactive console |
|
|
36
36
|
| `bin/setup` | Install dependencies |
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.41.0](https://github.com/janeapp/riffer/compare/riffer/v0.40.0...riffer/v0.41.0) (2026-08-14)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### ⚠ BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
* Inference providers no longer support extra configuration parameters (e.g. timeouts). Instead, a provider client object can be defined in the riffer config directly. Credential and endpoint parameters are still supported.
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* config-injected provider clients, retire provider_options ([#391](https://github.com/janeapp/riffer/issues/391)) ([72fa0e3](https://github.com/janeapp/riffer/commit/72fa0e32ff6cfeee29bae9e2618d001cbc387d99))
|
|
18
|
+
|
|
19
|
+
## [0.40.0](https://github.com/janeapp/riffer/compare/riffer/v0.39.0...riffer/v0.40.0) (2026-08-12)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* replace RDoc guide pages with a static docs site ([#390](https://github.com/janeapp/riffer/issues/390)) ([eef94e1](https://github.com/janeapp/riffer/commit/eef94e140b618ae55a0dea2e0e94cf91462ae169))
|
|
25
|
+
|
|
8
26
|
## [0.39.0](https://github.com/janeapp/riffer/compare/riffer/v0.38.1...riffer/v0.39.0) (2026-07-29)
|
|
9
27
|
|
|
10
28
|
|
data/README.md
CHANGED
|
@@ -45,35 +45,37 @@ puts agent.generate('Hello world')
|
|
|
45
45
|
|
|
46
46
|
## Documentation
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- [Overview](
|
|
51
|
-
- [Getting Started](
|
|
52
|
-
- [Agents](
|
|
53
|
-
- [Agent Lifecycle](
|
|
54
|
-
- [Agent Loop](
|
|
55
|
-
- [Tools](
|
|
56
|
-
- [Advanced Tools](
|
|
57
|
-
- [Messages](
|
|
58
|
-
- [Stream Events](
|
|
59
|
-
- [Configuration](
|
|
60
|
-
- [Evals](
|
|
61
|
-
- [Guardrails](
|
|
62
|
-
- [Skills](
|
|
63
|
-
- [MCP](
|
|
64
|
-
- [Serialization](
|
|
65
|
-
- [Tracing](
|
|
66
|
-
- [Providers](
|
|
48
|
+
Comprehensive guides live at [riffer.ai](https://riffer.ai):
|
|
49
|
+
|
|
50
|
+
- [Overview](https://riffer.ai/guides/overview/) - Core concepts and architecture
|
|
51
|
+
- [Getting Started](https://riffer.ai/guides/getting-started/) - Installation and first steps
|
|
52
|
+
- [Agents](https://riffer.ai/guides/agents/) - Defining and configuring agents
|
|
53
|
+
- [Agent Lifecycle](https://riffer.ai/guides/agent-lifecycle/) - Generate, stream, and responses
|
|
54
|
+
- [Agent Loop](https://riffer.ai/guides/agent-loop/) - Tool execution flow and stopping
|
|
55
|
+
- [Tools](https://riffer.ai/guides/tools/) - Creating tools for agents
|
|
56
|
+
- [Advanced Tools](https://riffer.ai/guides/advanced-tools/) - Timeouts, runtime, and registration
|
|
57
|
+
- [Messages](https://riffer.ai/guides/messages/) - Message types and formats
|
|
58
|
+
- [Stream Events](https://riffer.ai/guides/stream-events/) - Streaming responses
|
|
59
|
+
- [Configuration](https://riffer.ai/guides/configuration/) - Framework configuration
|
|
60
|
+
- [Evals](https://riffer.ai/guides/evals/) - Evaluating agent quality
|
|
61
|
+
- [Guardrails](https://riffer.ai/guides/guardrails/) - Input/output validation
|
|
62
|
+
- [Skills](https://riffer.ai/guides/skills/) - Packaged agent capabilities
|
|
63
|
+
- [MCP](https://riffer.ai/guides/mcp/) - Integrating third-party MCP servers
|
|
64
|
+
- [Serialization](https://riffer.ai/guides/serialization/) - Persisting and transferring agent definitions
|
|
65
|
+
- [Tracing](https://riffer.ai/guides/tracing/) - OpenTelemetry span contract and host wiring
|
|
66
|
+
- [Providers](https://riffer.ai/guides/providers/overview/) - LLM provider adapters
|
|
67
|
+
|
|
68
|
+
The guide sources are in the [docs](docs/) directory.
|
|
67
69
|
|
|
68
70
|
### API Reference
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
The full API reference is published at [riffer.ai/api](https://riffer.ai/api/). Preview the site locally with:
|
|
71
73
|
|
|
72
74
|
```bash
|
|
73
|
-
bin/docs
|
|
75
|
+
bin/rake docs:serve
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
Then open `
|
|
78
|
+
Then open <http://localhost:8000>. The site uses root-absolute paths, so it must be served over HTTP — opening `_site/index.html` via `file://` won't work.
|
|
77
79
|
|
|
78
80
|
## Development
|
|
79
81
|
|
|
@@ -86,17 +88,17 @@ bin/setup
|
|
|
86
88
|
Common workflows are wrapped in `bin/`. Each is a thin `exec bundle exec …` script — use them
|
|
87
89
|
instead of typing `bundle exec` yourself:
|
|
88
90
|
|
|
89
|
-
| Command | Description
|
|
90
|
-
| --------------- |
|
|
91
|
-
| `bin/rake` | Default task: test +
|
|
92
|
-
| `bin/test` | Run tests
|
|
93
|
-
| `bin/lint` | Check code style (pass
|
|
94
|
-
| `bin/typecheck` | Run Steep type checker
|
|
95
|
-
| `bin/rbs` | Generate RBS type signatures
|
|
96
|
-
| `bin/rbs-watch` | Watch and regenerate RBS files
|
|
97
|
-
| `bin/docs` | Build
|
|
98
|
-
| `bin/build` | Build the gem package
|
|
99
|
-
| `bin/console` | Interactive console
|
|
91
|
+
| Command | Description |
|
|
92
|
+
| --------------- | ------------------------------------------ |
|
|
93
|
+
| `bin/rake` | Default task: test + rubocop + steep:check |
|
|
94
|
+
| `bin/test` | Run tests |
|
|
95
|
+
| `bin/lint` | Check code style (pass `-a` to auto-fix) |
|
|
96
|
+
| `bin/typecheck` | Run Steep type checker |
|
|
97
|
+
| `bin/rbs` | Generate RBS type signatures |
|
|
98
|
+
| `bin/rbs-watch` | Watch and regenerate RBS files |
|
|
99
|
+
| `bin/docs` | Build the docs site + API reference |
|
|
100
|
+
| `bin/build` | Build the gem package |
|
|
101
|
+
| `bin/console` | Interactive console |
|
|
100
102
|
|
|
101
103
|
`bin/rake <task>` is the escape hatch for any rake task without a named wrapper (e.g.
|
|
102
104
|
`bin/rake test:slow`, `bin/rake release`).
|
|
@@ -138,7 +140,3 @@ All notable changes to this project are documented in `CHANGELOG.md`.
|
|
|
138
140
|
## License
|
|
139
141
|
|
|
140
142
|
Licensed under the MIT License. See `LICENSE.txt` for details.
|
|
141
|
-
|
|
142
|
-
## Maintainers
|
|
143
|
-
|
|
144
|
-
- Jake Bottrall - https://github.com/bottrall
|
data/Rakefile
CHANGED
|
@@ -5,20 +5,40 @@ require "minitest/test_task"
|
|
|
5
5
|
|
|
6
6
|
Minitest::TestTask.create
|
|
7
7
|
|
|
8
|
-
require "
|
|
8
|
+
require "rubocop/rake_task"
|
|
9
|
+
|
|
10
|
+
RuboCop::RakeTask.new
|
|
11
|
+
|
|
9
12
|
require "rdoc/task"
|
|
10
13
|
|
|
11
14
|
RDoc::Task.new do |rdoc|
|
|
12
|
-
rdoc.rdoc_dir = "
|
|
13
|
-
rdoc.title = "Riffer
|
|
15
|
+
rdoc.rdoc_dir = "_site/api"
|
|
16
|
+
rdoc.title = "Riffer API Reference"
|
|
14
17
|
rdoc.main = "README.md"
|
|
15
18
|
rdoc.rdoc_files.include("README.md", "CHANGELOG.md", "LICENSE.txt")
|
|
16
19
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
|
17
20
|
rdoc.options << "--charset" << "utf-8"
|
|
18
|
-
rdoc.options << "--page-dir" << "docs"
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
namespace :docs do
|
|
24
|
+
desc "Build the docs site (landing, guides, 404, assets) into _site/"
|
|
25
|
+
task :site do
|
|
26
|
+
ruby "docs-site/build.rb"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "Build the docs site and validate all internal links and anchors"
|
|
30
|
+
task check: :site do
|
|
31
|
+
ruby "docs-site/check.rb"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
desc "Build the docs site and serve it at http://localhost:8000"
|
|
35
|
+
task serve: :site do
|
|
36
|
+
ruby "-run -e httpd _site -p 8000"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
desc "Build the full deployable docs tree (site + API reference) into _site/"
|
|
41
|
+
task docs: %w[docs:site rdoc]
|
|
22
42
|
|
|
23
43
|
namespace :rbs do
|
|
24
44
|
desc "Generate RBS type signatures from inline annotations"
|
|
@@ -42,4 +62,4 @@ namespace :steep do
|
|
|
42
62
|
end
|
|
43
63
|
end
|
|
44
64
|
|
|
45
|
-
task default: %i[test
|
|
65
|
+
task default: %i[test rubocop steep:check]
|
data/Steepfile
CHANGED
|
@@ -126,18 +126,7 @@ end
|
|
|
126
126
|
|
|
127
127
|
### use_mcp
|
|
128
128
|
|
|
129
|
-
Loads tools from registered [MCP](
|
|
130
|
-
|
|
131
|
-
### provider_options
|
|
132
|
-
|
|
133
|
-
Passes options to the provider client:
|
|
134
|
-
|
|
135
|
-
```ruby
|
|
136
|
-
class MyAgent < Riffer::Agent
|
|
137
|
-
model 'openai/gpt-5-mini'
|
|
138
|
-
provider_options api_key: ENV['CUSTOM_OPENAI_KEY']
|
|
139
|
-
end
|
|
140
|
-
```
|
|
129
|
+
Loads tools from registered [MCP](MCP.md) servers by tag. Like `uses_tools`, **`use_mcp` is not inherited**—add it on each subclass that should include MCP tools.
|
|
141
130
|
|
|
142
131
|
### model_options
|
|
143
132
|
|
|
@@ -263,7 +252,7 @@ class MyAgent < Riffer::Agent
|
|
|
263
252
|
end
|
|
264
253
|
```
|
|
265
254
|
|
|
266
|
-
Accepts a `Riffer::Tools::Runtime` subclass, a `Riffer::Tools::Runtime` instance, or a `Proc`. When unset, defaults to `Riffer.config.tool_runtime` (captured at agent class definition time). See [Tools — Tool Runtime](
|
|
255
|
+
Accepts a `Riffer::Tools::Runtime` subclass, a `Riffer::Tools::Runtime` instance, or a `Proc`. When unset, defaults to `Riffer.config.tool_runtime` (captured at agent class definition time). See [Tools — Tool Runtime](TOOL_ADVANCED.md#tool-runtime-experimental) for details.
|
|
267
256
|
|
|
268
257
|
### guardrail
|
|
269
258
|
|
|
@@ -284,7 +273,7 @@ class MyAgent < Riffer::Agent
|
|
|
284
273
|
end
|
|
285
274
|
```
|
|
286
275
|
|
|
287
|
-
See [Guardrails](
|
|
276
|
+
See [Guardrails](GUARDRAILS.md) for detailed documentation.
|
|
288
277
|
|
|
289
278
|
## Configuration Object
|
|
290
279
|
|
|
@@ -333,7 +322,7 @@ Keys and values may be `String` or `Symbol`; both are stringified, and entries w
|
|
|
333
322
|
Tags propagate to **two** places:
|
|
334
323
|
|
|
335
324
|
1. The provider's native per-request metadata field (see the mapping below).
|
|
336
|
-
2. Observability — stamped as `riffer.tag.<key>` on **every** span the call emits (`invoke_agent`, `chat`, `execute_tool`, `execute_guardrail`). See [Tracing](
|
|
325
|
+
2. Observability — stamped as `riffer.tag.<key>` on **every** span the call emits (`invoke_agent`, `chat`, `execute_tool`, `execute_guardrail`). See [Tracing](TRACING.md).
|
|
337
326
|
|
|
338
327
|
### Reserved key: `user_id`
|
|
339
328
|
|
|
@@ -361,12 +350,12 @@ Riffer does not validate tag count, key/value length, or charset — it forwards
|
|
|
361
350
|
|
|
362
351
|
| Goal | Feature | Guide |
|
|
363
352
|
| ----------------------------- | ----------------- | -------------------------------------------------------------------- |
|
|
364
|
-
| Call APIs or run functions | Tools | [Tools](
|
|
353
|
+
| Call APIs or run functions | Tools | [Tools](TOOLS.md) |
|
|
365
354
|
| Return structured JSON | Structured Output | [structured_output](#structured_output) |
|
|
366
|
-
| Validate or filter content | Guardrails | [Guardrails](
|
|
367
|
-
| Measure output quality | Evals | [Evals](
|
|
368
|
-
| Add packaged capabilities | Skills | [Skills](
|
|
369
|
-
| Control the tool-use loop | Agent Loop | [Agent Loop](
|
|
370
|
-
| Human-in-the-loop approval | Interrupts | [Agent Lifecycle](
|
|
371
|
-
| Run tools concurrently | Tool Runtime | [Advanced Tools](
|
|
372
|
-
| Stream responses in real time | Streaming | [Agent Lifecycle](
|
|
355
|
+
| Validate or filter content | Guardrails | [Guardrails](GUARDRAILS.md) |
|
|
356
|
+
| Measure output quality | Evals | [Evals](EVALS.md) |
|
|
357
|
+
| Add packaged capabilities | Skills | [Skills](SKILLS.md) |
|
|
358
|
+
| Control the tool-use loop | Agent Loop | [Agent Loop](AGENT_LOOP.md) |
|
|
359
|
+
| Human-in-the-loop approval | Interrupts | [Agent Lifecycle](AGENT_LIFECYCLE.md#interrupting-the-agent-loop) |
|
|
360
|
+
| Run tools concurrently | Tool Runtime | [Advanced Tools](TOOL_ADVANCED.md#tool-runtime-experimental) |
|
|
361
|
+
| Stream responses in real time | Streaming | [Agent Lifecycle](AGENT_LIFECYCLE.md#stream) |
|
|
@@ -341,7 +341,7 @@ msg.structured_output? # => true
|
|
|
341
341
|
msg.structured_output # => {sentiment: "positive", score: 0.95}
|
|
342
342
|
```
|
|
343
343
|
|
|
344
|
-
See [Messages — Structured Output on Messages](
|
|
344
|
+
See [Messages — Structured Output on Messages](MESSAGES.md#structured-output-on-messages) for details.
|
|
345
345
|
|
|
346
346
|
## Class Methods
|
|
347
347
|
|