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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/architecture.md +2 -2
  3. data/.agents/code-style.md +4 -3
  4. data/.agents/providers.md +12 -3
  5. data/.agents/rbs-inline.md +2 -2
  6. data/.release-please-manifest.json +1 -1
  7. data/.rubocop.yml +112 -0
  8. data/AGENTS.md +6 -6
  9. data/CHANGELOG.md +18 -0
  10. data/README.md +35 -37
  11. data/Rakefile +26 -6
  12. data/Steepfile +2 -0
  13. data/docs/{03_AGENTS.md → AGENTS.md} +12 -23
  14. data/docs/{04_AGENT_LIFECYCLE.md → AGENT_LIFECYCLE.md} +1 -1
  15. data/docs/{10_CONFIGURATION.md → CONFIGURATION.md} +115 -31
  16. data/docs/{02_GETTING_STARTED.md → GETTING_STARTED.md} +6 -6
  17. data/docs/{14_MCP.md → MCP.md} +1 -1
  18. data/docs/{08_MESSAGES.md → MESSAGES.md} +4 -4
  19. data/docs/{01_OVERVIEW.md → OVERVIEW.md} +15 -15
  20. data/docs/{15_SERIALIZATION.md → SERIALIZATION.md} +8 -7
  21. data/docs/{09_STREAM_EVENTS.md → STREAM_EVENTS.md} +4 -4
  22. data/docs/{06_TOOLS.md → TOOLS.md} +1 -1
  23. data/docs/{16_TRACING.md → TRACING.md} +6 -6
  24. data/docs/providers/{02_AMAZON_BEDROCK.md → AMAZON_BEDROCK.md} +14 -8
  25. data/docs/providers/{03_ANTHROPIC.md → ANTHROPIC.md} +9 -7
  26. data/docs/providers/{05_AZURE_OPENAI.md → AZURE_OPENAI.md} +12 -12
  27. data/docs/providers/{07_CUSTOM_PROVIDERS.md → CUSTOM_PROVIDERS.md} +34 -18
  28. data/docs/providers/{08_GEMINI.md → GEMINI.md} +28 -5
  29. data/docs/providers/{04_OPENAI.md → OPENAI.md} +21 -5
  30. data/docs/providers/{09_OPENROUTER.md → OPENROUTER.md} +11 -6
  31. data/docs/providers/{01_PROVIDERS.md → PROVIDERS.md} +24 -9
  32. data/docs-site/404.html +51 -0
  33. data/docs-site/build.rb +144 -0
  34. data/docs-site/check.rb +64 -0
  35. data/docs-site/copy.js +20 -0
  36. data/docs-site/favicon.svg +18 -0
  37. data/docs-site/index.html.erb +194 -0
  38. data/docs-site/landing.css +315 -0
  39. data/docs-site/layout.html.erb +101 -0
  40. data/docs-site/manifest.yml +96 -0
  41. data/docs-site/site.css +598 -0
  42. data/lib/riffer/agent/config.rb +33 -14
  43. data/lib/riffer/agent/context.rb +6 -6
  44. data/lib/riffer/agent/response.rb +24 -2
  45. data/lib/riffer/agent/run.rb +121 -30
  46. data/lib/riffer/agent/serializer.rb +17 -10
  47. data/lib/riffer/agent/session/repair.rb +12 -11
  48. data/lib/riffer/agent/session.rb +16 -15
  49. data/lib/riffer/agent.rb +50 -20
  50. data/lib/riffer/config.rb +41 -18
  51. data/lib/riffer/evals/evaluator.rb +10 -3
  52. data/lib/riffer/evals/evaluator_runner.rb +3 -2
  53. data/lib/riffer/evals/judge.rb +7 -8
  54. data/lib/riffer/evals/result.rb +1 -1
  55. data/lib/riffer/evals/run_result.rb +3 -3
  56. data/lib/riffer/evals/scenario_result.rb +2 -2
  57. data/lib/riffer/guardrails/modification.rb +1 -1
  58. data/lib/riffer/guardrails/runner.rb +14 -9
  59. data/lib/riffer/guardrails/tripwire.rb +1 -1
  60. data/lib/riffer/helpers/boolean.rb +1 -1
  61. data/lib/riffer/helpers/call_or_value.rb +1 -0
  62. data/lib/riffer/helpers/class_name_converter.rb +6 -6
  63. data/lib/riffer/mcp/authenticated_tool.rb +2 -4
  64. data/lib/riffer/mcp/client.rb +2 -4
  65. data/lib/riffer/mcp/registry.rb +6 -2
  66. data/lib/riffer/mcp/search_tool.rb +1 -1
  67. data/lib/riffer/mcp/tool_factory.rb +5 -5
  68. data/lib/riffer/mcp.rb +1 -1
  69. data/lib/riffer/messages/assistant.rb +4 -3
  70. data/lib/riffer/messages/base.rb +13 -11
  71. data/lib/riffer/messages/file_part.rb +7 -6
  72. data/lib/riffer/messages/tool.rb +2 -2
  73. data/lib/riffer/messages/user.rb +2 -2
  74. data/lib/riffer/params/param.rb +8 -8
  75. data/lib/riffer/params.rb +31 -31
  76. data/lib/riffer/providers/amazon_bedrock.rb +79 -62
  77. data/lib/riffer/providers/anthropic.rb +82 -61
  78. data/lib/riffer/providers/azure_open_ai.rb +18 -16
  79. data/lib/riffer/providers/base.rb +68 -21
  80. data/lib/riffer/providers/gemini/client.rb +120 -0
  81. data/lib/riffer/providers/gemini.rb +47 -93
  82. data/lib/riffer/providers/mock.rb +27 -14
  83. data/lib/riffer/providers/open_ai.rb +62 -39
  84. data/lib/riffer/providers/open_router.rb +54 -41
  85. data/lib/riffer/providers/repository.rb +1 -1
  86. data/lib/riffer/providers/token_usage.rb +10 -8
  87. data/lib/riffer/runner/fibers.rb +7 -6
  88. data/lib/riffer/runner/sequential.rb +2 -2
  89. data/lib/riffer/runner/threaded.rb +4 -3
  90. data/lib/riffer/skills/adapter.rb +4 -2
  91. data/lib/riffer/skills/config.rb +7 -1
  92. data/lib/riffer/skills/context.rb +5 -1
  93. data/lib/riffer/skills/filesystem_backend.rb +2 -0
  94. data/lib/riffer/skills/frontmatter.rb +27 -5
  95. data/lib/riffer/stream_events/finish_reason_done.rb +3 -2
  96. data/lib/riffer/stream_events/guardrail_modification.rb +1 -1
  97. data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -1
  98. data/lib/riffer/stream_events/interrupt.rb +1 -1
  99. data/lib/riffer/stream_events/reasoning_delta.rb +1 -1
  100. data/lib/riffer/stream_events/reasoning_done.rb +1 -1
  101. data/lib/riffer/stream_events/skill_activation.rb +1 -1
  102. data/lib/riffer/stream_events/text_delta.rb +1 -1
  103. data/lib/riffer/stream_events/text_done.rb +1 -1
  104. data/lib/riffer/stream_events/token_usage_done.rb +1 -1
  105. data/lib/riffer/stream_events/tool_call_delta.rb +1 -1
  106. data/lib/riffer/stream_events/tool_call_done.rb +1 -1
  107. data/lib/riffer/stream_events/web_search_done.rb +1 -1
  108. data/lib/riffer/stream_events/web_search_status.rb +1 -1
  109. data/lib/riffer/tools/response.rb +3 -3
  110. data/lib/riffer/tools/runtime.rb +15 -7
  111. data/lib/riffer/tools/toolable.rb +17 -5
  112. data/lib/riffer/tracing/capture.rb +7 -7
  113. data/lib/riffer/tracing/no_op.rb +4 -8
  114. data/lib/riffer/tracing/otel.rb +8 -4
  115. data/lib/riffer/tracing/stream_recorder.rb +5 -1
  116. data/lib/riffer/tracing.rb +9 -6
  117. data/lib/riffer/version.rb +1 -1
  118. data/lib/riffer.rb +2 -2
  119. data/sig/_private/riffer/providers/amazon_bedrock.rbs +4 -2
  120. data/sig/_private/riffer/providers/anthropic.rbs +4 -2
  121. data/sig/_private/riffer/providers/gemini.rbs +7 -0
  122. data/sig/_private/riffer/providers/open_ai.rbs +4 -2
  123. data/sig/_private/riffer/providers/open_router.rbs +4 -2
  124. data/sig/generated/riffer/agent/config.rbs +14 -5
  125. data/sig/generated/riffer/agent/response.rbs +12 -1
  126. data/sig/generated/riffer/agent/run.rbs +12 -1
  127. data/sig/generated/riffer/agent.rbs +1 -7
  128. data/sig/generated/riffer/config.rbs +25 -15
  129. data/sig/generated/riffer/evals/judge.rbs +2 -4
  130. data/sig/generated/riffer/mcp.rbs +1 -1
  131. data/sig/generated/riffer/providers/amazon_bedrock.rbs +13 -2
  132. data/sig/generated/riffer/providers/anthropic.rbs +13 -2
  133. data/sig/generated/riffer/providers/azure_open_ai.rbs +14 -4
  134. data/sig/generated/riffer/providers/base.rbs +20 -0
  135. data/sig/generated/riffer/providers/gemini/client.rbs +65 -0
  136. data/sig/generated/riffer/providers/gemini.rbs +7 -23
  137. data/sig/generated/riffer/providers/mock.rbs +6 -4
  138. data/sig/generated/riffer/providers/open_ai.rbs +13 -2
  139. data/sig/generated/riffer/providers/open_router.rbs +16 -3
  140. metadata +41 -229
  141. data/.standard.yml +0 -1
  142. /data/docs/{05_AGENT_LOOP.md → AGENT_LOOP.md} +0 -0
  143. /data/docs/{11_EVALS.md → EVALS.md} +0 -0
  144. /data/docs/{12_GUARDRAILS.md → GUARDRAILS.md} +0 -0
  145. /data/docs/{13_SKILLS.md → SKILLS.md} +0 -0
  146. /data/docs/{07_TOOL_ADVANCED.md → TOOL_ADVANCED.md} +0 -0
  147. /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: b1bf92e3bef065a4c07aadb273a7f6770b711c0f15f268726133c841cb3fd510
4
- data.tar.gz: d7361c029b98ca819932e2c3d2d53113710bb434ad60092ee0578179fa844c5e
3
+ metadata.gz: fd309de6be56bd5fbe778bbf277b9125dd63d4ce7b360c3e5e85554a944cb81d
4
+ data.tar.gz: 965daf888849a0386b2826af572fd95d0a7fb8a4ac6f9f91788acb0254705f8e
5
5
  SHA512:
6
- metadata.gz: 7f503377743f6629a1423234afb158570dc33ee225c82c0bc46e28938a839fe25b5bdfad6f61da274a8bf81e1e8dd6c505ad826593c5eb269251d47667fe9d7c
7
- data.tar.gz: eddabf85e5416c777c3a9a441ce99cd1cb902ec1c339fa7338890ae8cb7e78c5e78628e1b886aea44cdc6228b99299fa3983816e10075d8c28b59229e4c0b376
6
+ metadata.gz: deedbd28b2c79faceea167422fb69147cb2453d7e06df48c46c2eb1e601068de7b9018026675a973f6de6036373d324d5120fc43269e863dd43ce39b88ee7ea4
7
+ data.tar.gz: 2007cc98bd5955ae2db4776e72551d546038deea60be3e397a5838e028cd2901465f2fe9c00d944b18e4ce9508599bcd7603ad61e0e75efaa8264793461cf283
@@ -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/14_MCP.md`).
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/14_MCP.md)
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
@@ -2,9 +2,10 @@
2
2
 
3
3
  ## Formatting
4
4
 
5
- - Use StandardRB for linting and formatting
6
- - Custom rules are defined in `.standard.yml`
7
- - Run `bin/lint` to check, `bin/lint --fix` to auto-fix
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/07_CUSTOM_PROVIDERS.md) for the full API)
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/07_CUSTOM_PROVIDERS.md).
54
+ For hook method signatures, structured output handling, file handling, and complete examples, see [Custom Providers](../docs/providers/CUSTOM_PROVIDERS.md).
@@ -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` declares the SDK-typed `@client` ivar).
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 ivars can't ship, so they go in `_private/riffer/providers/` (`@client`).
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
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.39.0"
2
+ ".": "0.41.0"
3
3
  }
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 + standard + steep:check)
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/10_CONFIGURATION.md`, `docs/08_MESSAGES.md`). RDoc ≠ user 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) - StandardRB, comment, and RDoc conventions
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 + standard + steep:check |
27
+ | `bin/rake` | Default task: test + rubocop + steep:check |
28
28
  | `bin/test` | Run tests |
29
- | `bin/lint` | Check code style (pass `--fix` to auto-fix) |
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 RDoc HTML |
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
- For comprehensive documentation, see the [docs](docs/) directory:
49
-
50
- - [Overview](docs/01_OVERVIEW.md) - Core concepts and architecture
51
- - [Getting Started](docs/02_GETTING_STARTED.md) - Installation and first steps
52
- - [Agents](docs/03_AGENTS.md) - Defining and configuring agents
53
- - [Agent Lifecycle](docs/04_AGENT_LIFECYCLE.md) - Generate, stream, and responses
54
- - [Agent Loop](docs/05_AGENT_LOOP.md) - Tool execution flow and stopping
55
- - [Tools](docs/06_TOOLS.md) - Creating tools for agents
56
- - [Advanced Tools](docs/07_TOOL_ADVANCED.md) - Timeouts, runtime, and registration
57
- - [Messages](docs/08_MESSAGES.md) - Message types and formats
58
- - [Stream Events](docs/09_STREAM_EVENTS.md) - Streaming responses
59
- - [Configuration](docs/10_CONFIGURATION.md) - Framework configuration
60
- - [Evals](docs/11_EVALS.md) - Evaluating agent quality
61
- - [Guardrails](docs/12_GUARDRAILS.md) - Input/output validation
62
- - [Skills](docs/13_SKILLS.md) - Packaged agent capabilities
63
- - [MCP](docs/14_MCP.md) - Integrating third-party MCP servers
64
- - [Serialization](docs/15_SERIALIZATION.md) - Persisting and transferring agent definitions
65
- - [Tracing](docs/16_TRACING.md) - OpenTelemetry span contract and host wiring
66
- - [Providers](docs/providers/01_PROVIDERS.md) - LLM provider adapters
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
- Generate the full API documentation with:
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 `doc/index.html` in your browser.
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 + standard + steep:check |
92
- | `bin/test` | Run tests |
93
- | `bin/lint` | Check code style (pass `--fix` to auto-fix) |
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 RDoc HTML |
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 "standard/rake"
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 = "doc"
13
- rdoc.title = "Riffer Documentation"
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
- task docs: :rdoc
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 standard steep:check]
65
+ task default: %i[test rubocop steep:check]
data/Steepfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  D = Steep::Diagnostic
2
4
 
3
5
  target :lib do
@@ -126,18 +126,7 @@ end
126
126
 
127
127
  ### use_mcp
128
128
 
129
- Loads tools from registered [MCP](14_MCP.md) servers by tag. Like `uses_tools`, **`use_mcp` is not inherited**—add it on each subclass that should include MCP tools.
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](07_TOOL_ADVANCED.md#tool-runtime-experimental) for details.
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](12_GUARDRAILS.md) for detailed documentation.
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](16_TRACING.md).
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](06_TOOLS.md) |
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](12_GUARDRAILS.md) |
367
- | Measure output quality | Evals | [Evals](11_EVALS.md) |
368
- | Add packaged capabilities | Skills | [Skills](13_SKILLS.md) |
369
- | Control the tool-use loop | Agent Loop | [Agent Loop](05_AGENT_LOOP.md) |
370
- | Human-in-the-loop approval | Interrupts | [Agent Lifecycle](04_AGENT_LIFECYCLE.md#interrupting-the-agent-loop) |
371
- | Run tools concurrently | Tool Runtime | [Advanced Tools](07_TOOL_ADVANCED.md#tool-runtime-experimental) |
372
- | Stream responses in real time | Streaming | [Agent Lifecycle](04_AGENT_LIFECYCLE.md#stream) |
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](08_MESSAGES.md#structured-output-on-messages) for details.
344
+ See [Messages — Structured Output on Messages](MESSAGES.md#structured-output-on-messages) for details.
345
345
 
346
346
  ## Class Methods
347
347