riffer 0.39.0 → 0.40.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 (130) 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 +2 -2
  5. data/.release-please-manifest.json +1 -1
  6. data/.rubocop.yml +112 -0
  7. data/AGENTS.md +6 -6
  8. data/CHANGELOG.md +7 -0
  9. data/README.md +35 -33
  10. data/Rakefile +26 -6
  11. data/Steepfile +2 -0
  12. data/docs/{03_AGENTS.md → AGENTS.md} +12 -12
  13. data/docs/{04_AGENT_LIFECYCLE.md → AGENT_LIFECYCLE.md} +1 -1
  14. data/docs/{10_CONFIGURATION.md → CONFIGURATION.md} +10 -10
  15. data/docs/{02_GETTING_STARTED.md → GETTING_STARTED.md} +6 -6
  16. data/docs/{14_MCP.md → MCP.md} +1 -1
  17. data/docs/{08_MESSAGES.md → MESSAGES.md} +4 -4
  18. data/docs/{01_OVERVIEW.md → OVERVIEW.md} +15 -15
  19. data/docs/{15_SERIALIZATION.md → SERIALIZATION.md} +4 -4
  20. data/docs/{09_STREAM_EVENTS.md → STREAM_EVENTS.md} +4 -4
  21. data/docs/{06_TOOLS.md → TOOLS.md} +1 -1
  22. data/docs/{16_TRACING.md → TRACING.md} +6 -6
  23. data/docs/providers/{07_CUSTOM_PROVIDERS.md → CUSTOM_PROVIDERS.md} +2 -2
  24. data/docs/providers/{01_PROVIDERS.md → PROVIDERS.md} +8 -8
  25. data/docs-site/404.html +51 -0
  26. data/docs-site/build.rb +144 -0
  27. data/docs-site/check.rb +64 -0
  28. data/docs-site/copy.js +20 -0
  29. data/docs-site/favicon.svg +18 -0
  30. data/docs-site/index.html.erb +194 -0
  31. data/docs-site/landing.css +315 -0
  32. data/docs-site/layout.html.erb +101 -0
  33. data/docs-site/manifest.yml +96 -0
  34. data/docs-site/site.css +598 -0
  35. data/lib/riffer/agent/config.rb +34 -9
  36. data/lib/riffer/agent/context.rb +6 -6
  37. data/lib/riffer/agent/response.rb +24 -2
  38. data/lib/riffer/agent/run.rb +121 -30
  39. data/lib/riffer/agent/serializer.rb +17 -8
  40. data/lib/riffer/agent/session/repair.rb +12 -11
  41. data/lib/riffer/agent/session.rb +16 -15
  42. data/lib/riffer/agent.rb +49 -11
  43. data/lib/riffer/config.rb +35 -12
  44. data/lib/riffer/evals/evaluator.rb +10 -3
  45. data/lib/riffer/evals/evaluator_runner.rb +3 -2
  46. data/lib/riffer/evals/judge.rb +4 -3
  47. data/lib/riffer/evals/result.rb +1 -1
  48. data/lib/riffer/evals/run_result.rb +3 -3
  49. data/lib/riffer/evals/scenario_result.rb +2 -2
  50. data/lib/riffer/guardrails/modification.rb +1 -1
  51. data/lib/riffer/guardrails/runner.rb +14 -9
  52. data/lib/riffer/guardrails/tripwire.rb +1 -1
  53. data/lib/riffer/helpers/boolean.rb +1 -1
  54. data/lib/riffer/helpers/call_or_value.rb +1 -0
  55. data/lib/riffer/helpers/class_name_converter.rb +6 -6
  56. data/lib/riffer/mcp/authenticated_tool.rb +2 -4
  57. data/lib/riffer/mcp/client.rb +2 -4
  58. data/lib/riffer/mcp/registry.rb +6 -2
  59. data/lib/riffer/mcp/search_tool.rb +1 -1
  60. data/lib/riffer/mcp/tool_factory.rb +5 -5
  61. data/lib/riffer/mcp.rb +1 -1
  62. data/lib/riffer/messages/assistant.rb +4 -3
  63. data/lib/riffer/messages/base.rb +13 -11
  64. data/lib/riffer/messages/file_part.rb +7 -6
  65. data/lib/riffer/messages/tool.rb +2 -2
  66. data/lib/riffer/messages/user.rb +2 -2
  67. data/lib/riffer/params/param.rb +8 -8
  68. data/lib/riffer/params.rb +31 -31
  69. data/lib/riffer/providers/amazon_bedrock.rb +64 -59
  70. data/lib/riffer/providers/anthropic.rb +66 -56
  71. data/lib/riffer/providers/azure_open_ai.rb +7 -13
  72. data/lib/riffer/providers/base.rb +40 -21
  73. data/lib/riffer/providers/gemini.rb +38 -35
  74. data/lib/riffer/providers/mock.rb +22 -10
  75. data/lib/riffer/providers/open_ai.rb +40 -32
  76. data/lib/riffer/providers/open_router.rb +35 -36
  77. data/lib/riffer/providers/repository.rb +1 -1
  78. data/lib/riffer/providers/token_usage.rb +10 -8
  79. data/lib/riffer/runner/fibers.rb +7 -6
  80. data/lib/riffer/runner/sequential.rb +2 -2
  81. data/lib/riffer/runner/threaded.rb +4 -3
  82. data/lib/riffer/skills/adapter.rb +4 -2
  83. data/lib/riffer/skills/config.rb +7 -1
  84. data/lib/riffer/skills/context.rb +5 -1
  85. data/lib/riffer/skills/filesystem_backend.rb +2 -0
  86. data/lib/riffer/skills/frontmatter.rb +27 -5
  87. data/lib/riffer/stream_events/finish_reason_done.rb +3 -2
  88. data/lib/riffer/stream_events/guardrail_modification.rb +1 -1
  89. data/lib/riffer/stream_events/guardrail_tripwire.rb +1 -1
  90. data/lib/riffer/stream_events/interrupt.rb +1 -1
  91. data/lib/riffer/stream_events/reasoning_delta.rb +1 -1
  92. data/lib/riffer/stream_events/reasoning_done.rb +1 -1
  93. data/lib/riffer/stream_events/skill_activation.rb +1 -1
  94. data/lib/riffer/stream_events/text_delta.rb +1 -1
  95. data/lib/riffer/stream_events/text_done.rb +1 -1
  96. data/lib/riffer/stream_events/token_usage_done.rb +1 -1
  97. data/lib/riffer/stream_events/tool_call_delta.rb +1 -1
  98. data/lib/riffer/stream_events/tool_call_done.rb +1 -1
  99. data/lib/riffer/stream_events/web_search_done.rb +1 -1
  100. data/lib/riffer/stream_events/web_search_status.rb +1 -1
  101. data/lib/riffer/tools/response.rb +3 -3
  102. data/lib/riffer/tools/runtime.rb +15 -7
  103. data/lib/riffer/tools/toolable.rb +17 -5
  104. data/lib/riffer/tracing/capture.rb +7 -7
  105. data/lib/riffer/tracing/no_op.rb +4 -8
  106. data/lib/riffer/tracing/otel.rb +8 -4
  107. data/lib/riffer/tracing/stream_recorder.rb +5 -1
  108. data/lib/riffer/tracing.rb +9 -6
  109. data/lib/riffer/version.rb +1 -1
  110. data/lib/riffer.rb +2 -2
  111. data/sig/generated/riffer/agent/config.rbs +14 -1
  112. data/sig/generated/riffer/agent/response.rbs +12 -1
  113. data/sig/generated/riffer/agent/run.rbs +12 -1
  114. data/sig/generated/riffer/agent.rbs +1 -1
  115. data/sig/generated/riffer/mcp.rbs +1 -1
  116. data/sig/generated/riffer/providers/mock.rbs +2 -1
  117. metadata +38 -229
  118. data/.standard.yml +0 -1
  119. /data/docs/{05_AGENT_LOOP.md → AGENT_LOOP.md} +0 -0
  120. /data/docs/{11_EVALS.md → EVALS.md} +0 -0
  121. /data/docs/{12_GUARDRAILS.md → GUARDRAILS.md} +0 -0
  122. /data/docs/{13_SKILLS.md → SKILLS.md} +0 -0
  123. /data/docs/{07_TOOL_ADVANCED.md → TOOL_ADVANCED.md} +0 -0
  124. /data/docs/providers/{02_AMAZON_BEDROCK.md → AMAZON_BEDROCK.md} +0 -0
  125. /data/docs/providers/{03_ANTHROPIC.md → ANTHROPIC.md} +0 -0
  126. /data/docs/providers/{05_AZURE_OPENAI.md → AZURE_OPENAI.md} +0 -0
  127. /data/docs/providers/{08_GEMINI.md → GEMINI.md} +0 -0
  128. /data/docs/providers/{06_MOCK_PROVIDER.md → MOCK_PROVIDER.md} +0 -0
  129. /data/docs/providers/{04_OPENAI.md → OPENAI.md} +0 -0
  130. /data/docs/providers/{09_OPENROUTER.md → OPENROUTER.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: 6c89776aeb032fbf837df103366fed830edcc20769cc9d4958a3a9bfa56a7803
4
+ data.tar.gz: 2153cf2967b9b70366987aeb9e59b215ff641bcd44668525c07d822ff9757579
5
5
  SHA512:
6
- metadata.gz: 7f503377743f6629a1423234afb158570dc33ee225c82c0bc46e28938a839fe25b5bdfad6f61da274a8bf81e1e8dd6c505ad826593c5eb269251d47667fe9d7c
7
- data.tar.gz: eddabf85e5416c777c3a9a441ce99cd1cb902ec1c339fa7338890ae8cb7e78c5e78628e1b886aea44cdc6228b99299fa3983816e10075d8c28b59229e4c0b376
6
+ metadata.gz: edfb2a10f17e1c0f6fb0630f5c2244370e01c5f32d05e9f065183da0b5b2d2cfec2453cac9a08714bd921716cd747609e4db61fb105a57769d79ab2f8988356a
7
+ data.tar.gz: 7d6dcdbab4be152033fcf75581252d3c9bda60c9e49825e75028d19670bae0490087ee8a90267a2af2f4fd8daabb5f370c8c2b7bb7cdcffe77a75b94a6b190ff
@@ -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,7 +3,7 @@
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
8
  4. Add provider config to `Riffer::Config` if needed
9
9
  5. Create tests in `test/riffer/providers/your_provider_test.rb`
@@ -42,4 +42,4 @@ Use `depends_on` helper for runtime dependency checking if your provider require
42
42
 
43
43
  ## Reference
44
44
 
45
- For hook method signatures, structured output handling, file handling, and complete examples, see [Custom Providers](../docs/providers/07_CUSTOM_PROVIDERS.md).
45
+ For hook method signatures, structured output handling, file handling, and complete examples, see [Custom Providers](../docs/providers/CUSTOM_PROVIDERS.md).
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.39.0"
2
+ ".": "0.40.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,13 @@ 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.40.0](https://github.com/janeapp/riffer/compare/riffer/v0.39.0...riffer/v0.40.0) (2026-08-12)
9
+
10
+
11
+ ### Features
12
+
13
+ * 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))
14
+
8
15
  ## [0.39.0](https://github.com/janeapp/riffer/compare/riffer/v0.38.1...riffer/v0.39.0) (2026-07-29)
9
16
 
10
17
 
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 [docs.riffer.ai](https://docs.riffer.ai):
49
+
50
+ - [Overview](https://docs.riffer.ai/guides/overview/) - Core concepts and architecture
51
+ - [Getting Started](https://docs.riffer.ai/guides/getting-started/) - Installation and first steps
52
+ - [Agents](https://docs.riffer.ai/guides/agents/) - Defining and configuring agents
53
+ - [Agent Lifecycle](https://docs.riffer.ai/guides/agent-lifecycle/) - Generate, stream, and responses
54
+ - [Agent Loop](https://docs.riffer.ai/guides/agent-loop/) - Tool execution flow and stopping
55
+ - [Tools](https://docs.riffer.ai/guides/tools/) - Creating tools for agents
56
+ - [Advanced Tools](https://docs.riffer.ai/guides/advanced-tools/) - Timeouts, runtime, and registration
57
+ - [Messages](https://docs.riffer.ai/guides/messages/) - Message types and formats
58
+ - [Stream Events](https://docs.riffer.ai/guides/stream-events/) - Streaming responses
59
+ - [Configuration](https://docs.riffer.ai/guides/configuration/) - Framework configuration
60
+ - [Evals](https://docs.riffer.ai/guides/evals/) - Evaluating agent quality
61
+ - [Guardrails](https://docs.riffer.ai/guides/guardrails/) - Input/output validation
62
+ - [Skills](https://docs.riffer.ai/guides/skills/) - Packaged agent capabilities
63
+ - [MCP](https://docs.riffer.ai/guides/mcp/) - Integrating third-party MCP servers
64
+ - [Serialization](https://docs.riffer.ai/guides/serialization/) - Persisting and transferring agent definitions
65
+ - [Tracing](https://docs.riffer.ai/guides/tracing/) - OpenTelemetry span contract and host wiring
66
+ - [Providers](https://docs.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 [docs.riffer.ai/api](https://docs.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`).
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,7 +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.
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.
130
130
 
131
131
  ### provider_options
132
132
 
@@ -263,7 +263,7 @@ class MyAgent < Riffer::Agent
263
263
  end
264
264
  ```
265
265
 
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.
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](TOOL_ADVANCED.md#tool-runtime-experimental) for details.
267
267
 
268
268
  ### guardrail
269
269
 
@@ -284,7 +284,7 @@ class MyAgent < Riffer::Agent
284
284
  end
285
285
  ```
286
286
 
287
- See [Guardrails](12_GUARDRAILS.md) for detailed documentation.
287
+ See [Guardrails](GUARDRAILS.md) for detailed documentation.
288
288
 
289
289
  ## Configuration Object
290
290
 
@@ -333,7 +333,7 @@ Keys and values may be `String` or `Symbol`; both are stringified, and entries w
333
333
  Tags propagate to **two** places:
334
334
 
335
335
  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).
336
+ 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
337
 
338
338
  ### Reserved key: `user_id`
339
339
 
@@ -361,12 +361,12 @@ Riffer does not validate tag count, key/value length, or charset — it forwards
361
361
 
362
362
  | Goal | Feature | Guide |
363
363
  | ----------------------------- | ----------------- | -------------------------------------------------------------------- |
364
- | Call APIs or run functions | Tools | [Tools](06_TOOLS.md) |
364
+ | Call APIs or run functions | Tools | [Tools](TOOLS.md) |
365
365
  | 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) |
366
+ | Validate or filter content | Guardrails | [Guardrails](GUARDRAILS.md) |
367
+ | Measure output quality | Evals | [Evals](EVALS.md) |
368
+ | Add packaged capabilities | Skills | [Skills](SKILLS.md) |
369
+ | Control the tool-use loop | Agent Loop | [Agent Loop](AGENT_LOOP.md) |
370
+ | Human-in-the-loop approval | Interrupts | [Agent Lifecycle](AGENT_LIFECYCLE.md#interrupting-the-agent-loop) |
371
+ | Run tools concurrently | Tool Runtime | [Advanced Tools](TOOL_ADVANCED.md#tool-runtime-experimental) |
372
+ | 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
 
@@ -32,11 +32,11 @@ Riffer.config.anthropic.api_key
32
32
 
33
33
  ## Provider-Specific Configuration
34
34
 
35
- For provider credentials and setup, see the individual [Provider guides](providers/).
35
+ For provider credentials and setup, see the individual [Provider guides](providers/PROVIDERS.md).
36
36
 
37
37
  ### MCP (Model Context Protocol)
38
38
 
39
- Optional settings for [MCP server integrations](14_MCP.md):
39
+ Optional settings for [MCP server integrations](MCP.md):
40
40
 
41
41
  | Option | Description |
42
42
  | ------------------ | --------------------------------------------------------------------------------------------------------------- |
@@ -51,7 +51,7 @@ Riffer.configure do |config|
51
51
  end
52
52
  ```
53
53
 
54
- See [MCP](14_MCP.md) for registration, tags, and agent `use_mcp`.
54
+ See [MCP](MCP.md) for registration, tags, and agent `use_mcp`.
55
55
 
56
56
  ### Tool Runtime (Experimental)
57
57
 
@@ -71,7 +71,7 @@ end
71
71
  | `Riffer::Tools::Runtime` instance | Custom runtime with specific options |
72
72
  | `Proc` | Dynamic resolution |
73
73
 
74
- Per-agent configuration overrides this global default. See [Advanced Tool Configuration — Tool Runtime](07_TOOL_ADVANCED.md#tool-runtime-experimental) for details.
74
+ Per-agent configuration overrides this global default. See [Advanced Tool Configuration — Tool Runtime](TOOL_ADVANCED.md#tool-runtime-experimental) for details.
75
75
 
76
76
  ### Skills
77
77
 
@@ -87,7 +87,7 @@ Riffer.configure do |config|
87
87
  end
88
88
  ```
89
89
 
90
- Per-agent override is available inside the `skills` block via `activate_tool MyCustomActivateTool`. See [Skills — Custom Activation Tool](13_SKILLS.md#custom-activation-tool).
90
+ Per-agent override is available inside the `skills` block via `activate_tool MyCustomActivateTool`. See [Skills — Custom Activation Tool](SKILLS.md#custom-activation-tool).
91
91
 
92
92
  #### Default backend
93
93
 
@@ -117,11 +117,11 @@ end
117
117
  | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
118
118
  | `enabled` | The kill switch, consulted on every span — flipping it at runtime takes effect immediately, short-circuiting to a no-op ahead of the backend. Accepts booleans or `'true'`/`'false'`/`'1'`/`'0'`. Defaults to `true`. |
119
119
  | `capture_messages` | Opt-in capture of full message content on LLM-call spans (`gen_ai.input.messages`, `gen_ai.output.messages`, `gen_ai.system_instructions`) as GenAI-semconv JSON. Defaults to `false` — message content routinely carries sensitive data. File attachments serialize as metadata-only stubs (media type and name, never bytes), and riffer applies no size limit of its own — cap oversized attributes with the OTEL SDK attribute length limits. |
120
- | `backend` | The backend riffer routes spans through. Assign `Riffer::Tracing::Otel.build` (pass `provider:` to override the global tracer provider — e.g. an in-memory provider in tests), or any object satisfying the duck-typed contract (`in_span` / `current_context` / `with_context`) to route into a non-OTEL system (e.g. Datadog APM). Defaults to `nil` — a no-op. Raises `Riffer::ArgumentError` unless the value is `nil` or responds to `in_span`. See [Tracing → Routing to a non-OpenTelemetry backend](16_TRACING.md#routing-to-a-non-opentelemetry-backend). |
120
+ | `backend` | The backend riffer routes spans through. Assign `Riffer::Tracing::Otel.build` (pass `provider:` to override the global tracer provider — e.g. an in-memory provider in tests), or any object satisfying the duck-typed contract (`in_span` / `current_context` / `with_context`) to route into a non-OTEL system (e.g. Datadog APM). Defaults to `nil` — a no-op. Raises `Riffer::ArgumentError` unless the value is `nil` or responds to `in_span`. See [Tracing → Routing to a non-OpenTelemetry backend](TRACING.md#routing-to-a-non-opentelemetry-backend). |
121
121
 
122
122
  ### Pricing
123
123
 
124
- Configure per-model token prices and riffer computes the cost of each LLM call onto its [`TokenUsage`](08_MESSAGES.md#token-usage-semantics). Riffer ships **no** price table — so an unconfigured model simply carries no cost (`token_usage.cost` is `nil`).
124
+ Configure per-model token prices and riffer computes the cost of each LLM call onto its [`TokenUsage`](MESSAGES.md#token-usage-semantics). Riffer ships **no** price table — so an unconfigured model simply carries no cost (`token_usage.cost` is `nil`).
125
125
 
126
126
  ```ruby
127
127
  Riffer.configure do |config|
@@ -151,7 +151,7 @@ cost = (input − cache_read − cache_write) × input_rate
151
151
  + output × output_rate
152
152
  ```
153
153
 
154
- (all rates ÷ 1,000,000; an unset cache rate falls back to `input_rate`.) Cost is for observability, not billing — it's a `Float`, and sub-cent rounding can accumulate over a long run. See [Messages → Token Usage Semantics](08_MESSAGES.md#token-usage-semantics) for how cost surfaces and aggregates.
154
+ (all rates ÷ 1,000,000; an unset cache rate falls back to `input_rate`.) Cost is for observability, not billing — it's a `Float`, and sub-cent rounding can accumulate over a long run. See [Messages → Token Usage Semantics](MESSAGES.md#token-usage-semantics) for how cost surfaces and aggregates.
155
155
 
156
156
  ### Message ID Strategy
157
157
 
@@ -173,7 +173,7 @@ When the strategy is not `:none`, every `Riffer::Messages::Base` instance — us
173
173
 
174
174
  When constructing a `Riffer::Agent::Session` from persisted history with the strategy enabled, supply ids on every seeded message yourself — Riffer never fabricates identifiers for pre-existing history. Messages built via the `Riffer::Messages::*` constructors auto-generate ids per the strategy, so as long as those constructors are used at message-creation time, ids flow through.
175
175
 
176
- See [Messages — IDs](08_MESSAGES.md#ids) for more details.
176
+ See [Messages — IDs](MESSAGES.md#ids) for more details.
177
177
 
178
178
  ### Experimental: History Healing
179
179
 
@@ -194,7 +194,7 @@ When enabled, two repairs run automatically:
194
194
 
195
195
  Defaults to `false` — pre-healing behavior. Seeded sessions pass through untouched, and orphan `tool_use` left by an interrupt remain in history for `execute_pending_tool_calls` to re-run on the next call.
196
196
 
197
- There is no per-call override and no customizable placeholder. Callers needing finer control can call `agent.session.update(tool_call_id:, ...)` after the interrupt returns to upgrade a placeholder in place. See [Agent Lifecycle — Healing pending tool results on interrupt](04_AGENT_LIFECYCLE.md#healing-pending-tool-results-on-interrupt-experimental).
197
+ There is no per-call override and no customizable placeholder. Callers needing finer control can call `agent.session.update(tool_call_id:, ...)` after the interrupt returns to upgrade a placeholder in place. See [Agent Lifecycle — Healing pending tool results on interrupt](AGENT_LIFECYCLE.md#healing-pending-tool-results-on-interrupt-experimental).
198
198
 
199
199
  ## Agent-Level Configuration
200
200
 
@@ -24,7 +24,7 @@ gem install riffer
24
24
 
25
25
  ## Provider Setup
26
26
 
27
- Riffer requires an LLM provider. See [Providers](providers/01_PROVIDERS.md) for setup instructions for each supported provider.
27
+ Riffer requires an LLM provider. See [Providers](providers/PROVIDERS.md) for setup instructions for each supported provider.
28
28
 
29
29
  ## Creating Your First Agent
30
30
 
@@ -91,8 +91,8 @@ puts agent.generate("What time is it?")
91
91
 
92
92
  ## Next Steps
93
93
 
94
- - [Agents](03_AGENTS.md) - Agent configuration options
95
- - [Tools](06_TOOLS.md) - Creating tools with parameters
96
- - [Messages](08_MESSAGES.md) - Message types and history
97
- - [Stream Events](09_STREAM_EVENTS.md) - Streaming event types
98
- - [Providers](providers/01_PROVIDERS.md) - Provider-specific guides
94
+ - [Agents](AGENTS.md) - Agent configuration options
95
+ - [Tools](TOOLS.md) - Creating tools with parameters
96
+ - [Messages](MESSAGES.md) - Message types and history
97
+ - [Stream Events](STREAM_EVENTS.md) - Streaming event types
98
+ - [Providers](providers/PROVIDERS.md) - Provider-specific guides
@@ -91,7 +91,7 @@ Tool names must be unique across `uses_tools` and all included MCP servers; dupl
91
91
 
92
92
  ### Subclassing
93
93
 
94
- Like [`uses_tools`](03_AGENTS.md#uses_tools), **`use_mcp` is not inherited** from the superclass. Declare `use_mcp` on each agent class that should load MCP tools.
94
+ Like [`uses_tools`](AGENTS.md#uses_tools), **`use_mcp` is not inherited** from the superclass. Declare `use_mcp` on each agent class that should load MCP tools.
95
95
 
96
96
  ## Progressive Tool Discovery
97
97
 
@@ -77,7 +77,7 @@ end
77
77
 
78
78
  The cache buckets are subsets of `input_tokens`, never additions to it — summing `input_tokens + cache_read_tokens` double-counts. `total_tokens` (input + output) matches the totals providers report on their dashboards.
79
79
 
80
- - `cost` — the computed cost of the call, set when pricing is configured for the model in use (see [Configuration → Pricing](10_CONFIGURATION.md#pricing)); `nil` when the model is unpriced. It's for observability, not billing. Run-level usage sums per-call costs through `TokenUsage#+`, so `response.token_usage.cost` is the total spend across the run — but the sum is `nil` if any call in the run used an unpriced model, rather than silently under-reporting.
80
+ - `cost` — the computed cost of the call, set when pricing is configured for the model in use (see [Configuration → Pricing](CONFIGURATION.md#pricing)); `nil` when the model is unpriced. It's for observability, not billing. Run-level usage sums per-call costs through `TokenUsage#+`, so `response.token_usage.cost` is the total spend across the run — but the sum is `nil` if any call in the run used an unpriced model, rather than silently under-reporting.
81
81
 
82
82
  #### Finish Reasons
83
83
 
@@ -269,7 +269,7 @@ When creating tool result messages, use the `id` as `tool_call_id`.
269
269
 
270
270
  Agents can emit messages as they're added during generation via the `on_message` callback. This is useful for persistence or real-time logging. Only agent-generated messages (Assistant, Tool) are emitted—not inputs (System, User).
271
271
 
272
- See [Agent Lifecycle - on_message](04_AGENT_LIFECYCLE.md#on_message) for details.
272
+ See [Agent Lifecycle - on_message](AGENT_LIFECYCLE.md#on_message) for details.
273
273
 
274
274
  ## Consecutive Message Merging
275
275
 
@@ -317,7 +317,7 @@ msg.id # => "0195a2e1-..." (auto-generated UUIDv7)
317
317
  msg.to_h # => {role: :user, content: "Hello", id: "0195a2e1-..."}
318
318
  ```
319
319
 
320
- Supported strategies: `:none` (default), `:uuid`, `:uuidv7`. See [Configuration — Message ID Strategy](10_CONFIGURATION.md#message-id-strategy) for the full reference.
320
+ Supported strategies: `:none` (default), `:uuid`, `:uuidv7`. See [Configuration — Message ID Strategy](CONFIGURATION.md#message-id-strategy) for the full reference.
321
321
 
322
322
  Ids pass through to subclass constructors via an `id:` kwarg and are preserved when set explicitly:
323
323
 
@@ -357,4 +357,4 @@ Subclasses implement `role` and optionally extend `to_h` with additional fields.
357
357
 
358
358
  ## Editing history after the fact
359
359
 
360
- The session's `messages` array is mutable, but the message value objects themselves are immutable. To edit recorded history — truncate an assistant message, rewrite a tool result, fill an orphan `tool_use` — use the mutators on `agent.session` (`update`, `remove`). Each one enforces the `tool_use` ↔ `tool_result` invariant. See [Mutating history](04_AGENT_LIFECYCLE.md#mutating-history) for the full list.
360
+ The session's `messages` array is mutable, but the message value objects themselves are immutable. To edit recorded history — truncate an assistant message, rewrite a tool result, fill an orphan `tool_use` — use the mutators on `agent.session` (`update`, `remove`). Each one enforces the `tool_use` ↔ `tool_result` invariant. See [Mutating history](AGENT_LIFECYCLE.md#mutating-history) for the full list.