experimental(agent): Add experimental coding-agent adapters with NeMo-Relay telemetry#1995
experimental(agent): Add experimental coding-agent adapters with NeMo-Relay telemetry#1995yczhang-nv wants to merge 13 commits into
Conversation
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
WalkthroughAdds five experimental agent adapters (Claude Code, Codex, Cursor, Hermes, OpenClaw) with docs, packaging, and YAML configs; a new relay telemetry bridge converting NeMo Relay ATOF JSONL into NAT IntermediateStep objects with tests; and CI/path-check and .gitignore updates. ChangesExperimental Agent Adapters with Relay Integration
🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…ration Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
…de-agent-adapter Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (4)
packages/nvidia_nat_core/tests/nat/experimental/test_relay_telemetry_bridge.py (1)
124-145: ⚡ Quick winConsider a negative-path test for malformed JSONL.
Once
load_atof_jsonlis hardened to skip bad lines, add a case writing a partial/invalid line to confirm valid events are still loaded. This guards the Relay timeout injection path.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/nvidia_nat_core/tests/nat/experimental/test_relay_telemetry_bridge.py` around lines 124 - 145, Add a negative-path test that writes a JSONL file containing both a valid event and a malformed/partial line, then call load_atof_jsonl and inject_atof_jsonl to verify the loader skips the bad line and only returns/injects the valid event: create a file with one well-formed event JSON and one broken line, assert load_atof_jsonl(path) returns only the valid event, subscribe to Context.intermediate_step_manager, call inject_atof_jsonl(path, context=...), and assert the captured IntermediateStep(s) correspond only to the valid event (check event types, parent_id, and count).packages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.py (1)
66-83: 💤 Low valueDocstring style: prefer Google-style.
The docstring uses NumPy-style
Parameters\n----------sections. As per coding guidelines, "Provide Google-style docstrings for every public module, class, function and CLI command" (i.e. anArgs:section).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.py` around lines 66 - 83, The docstring for relay_events_to_intermediate_steps uses NumPy-style Parameters/---------- formatting; update it to a Google-style docstring: replace the Parameters section with an Args: block listing events, root_parent_id, and function_ancestry (each with a one-line description and types where helpful), and keep the brief top description and Returns/Examples if present in Google style; ensure the function name relay_events_to_intermediate_steps and parameter names root_parent_id and function_ancestry are referenced exactly as in the signature.examples/experimental/claude_code_agent_adapter/src/nat_claude_code_agent_adapter/register.py (1)
376-379: 💤 Low valueUnreachable non-relay CLI branch.
_run_claude_codeonly routes to_run_claude_code_cliwhenrelay_enabledis true; otherwise it uses the SDK path. As a result theelsebranch in_run_claude_code_cli(lines 327-328,_build_claude_command) and the non-relay portions of theFileNotFoundErrormessaging are dead code. Either wire up a CLI fallback for the non-relay case or drop the unused branch to avoid confusion.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/experimental/claude_code_agent_adapter/src/nat_claude_code_agent_adapter/register.py` around lines 376 - 379, The current routing makes the CLI path unreachable unless config.relay_enabled is true, leaving the else branch in _run_claude_code_cli and parts of the FileNotFoundError message unused; either remove the dead CLI fallback code (drop the else branch in _run_claude_code_cli and related non-relay FileNotFoundError text) or add a clear CLI fallback path by updating _run_claude_code to call _run_claude_code_cli when relay is disabled (or when a new config flag indicates CLI mode), and ensure _build_claude_command is invoked only in the supported branch; modify the logic in _run_claude_code, _run_claude_code_cli, and any FileNotFoundError messaging accordingly so there is no dead-code path left.examples/experimental/openclaw_agent_adapter/README.md (1)
58-58: 💤 Low valueAvoid possessive
'swith inanimate objects (doc style)."OpenClaw's plugin system" (and "the example's ..." on Line 308) use possessive
'swith inanimate nouns. Reword, e.g. "the plugin system of OpenClaw" / "the example settings".As per coding guidelines: "Documentation in Markdown files should not contain usage of a possessive 's with inanimate objects."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@examples/experimental/openclaw_agent_adapter/README.md` at line 58, Replace possessive "'s" usages with "of" phrasing for inanimate nouns: change "OpenClaw's plugin system" to "the plugin system of OpenClaw" and "the example's ..." to "the example settings" (or "settings of the example") in the README content; search for and update any other occurrences of possessive "'s" applied to inanimate objects so documentation follows the style guideline.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@examples/experimental/claude_code_agent_adapter/pyproject.toml`:
- Around line 27-45: Add the example to the root project examples list and
rename the uv source to a nat_-prefixed name: in root pyproject.toml include
"nat_claude_code_agent_adapter" in the examples/installable examples array so
the example is packaged, and in
examples/experimental/claude_code_agent_adapter/pyproject.toml change the
[tool.uv.sources] key from "nvidia-nat" to a nat_-prefixed identifier (e.g.,
"nat_nvidia_nat" or "nat_nvidia-nat") so the source reads like nat_nvidia_nat =
{ path = "../../..", editable = true }; leave the project.name and the entry
point nat_claude_code_agent_adapter = "nat_claude_code_agent_adapter.register"
intact.
In `@examples/experimental/codex_agent_adapter/package.json`:
- Around line 4-6: Update the dependency declaration for `@openai/codex-sdk` in
package.json to pin it to the tested version/range instead of "latest" — replace
the current "`@openai/codex-sdk`": "latest" entry with a stable version (e.g.,
"`@openai/codex-sdk`": "0.135.0" or a constrained range "`@openai/codex-sdk`":
"^0.135.0") so installs align with the package-lock.json and the README's
supported Codex version.
In `@examples/experimental/codex_agent_adapter/pyproject.toml`:
- Around line 30-47: The root pyproject.toml needs the new example registered:
add "nat_codex_agent_adapter" to the top-level examples = [...] array and add a
corresponding [tool.uv.sources] entry named nat_codex_agent_adapter that points
to the example path (nat_codex_agent_adapter = { path =
"examples/experimental/codex_agent_adapter", editable = true }) so the package
declared as name = "nat_codex_agent_adapter" and the entry point nat.components
-> nat_codex_agent_adapter = "nat_codex_agent_adapter.register" in the example
pyproject.toml is discoverable by the root build/configuration.
In
`@examples/experimental/codex_agent_adapter/src/nat_codex_agent_adapter/register.py`:
- Around line 397-400: The `_run_codex_cli` implementation contains a dead
non-relay branch (the `else: command = _build_codex_command(...)` path) that is
never used because `_run_codex` only calls `_run_codex_cli` when
`config.relay_enabled` is true and all non-relay calls go to `_run_node_sdk`;
remove the unreachable branch (and the helper `_build_codex_command` if it
becomes unused) or, if you intended to support non-relay CLI execution, change
`_run_codex` to route non-relay calls into `_run_codex_cli`. Also update the
`FileNotFoundError` handler wording inside `_run_codex_cli` to refer
specifically to the Codex relay binary (and remove “Codex CLI” wording) so the
error message matches the actual execution path. Ensure any removed helper
references (e.g., `_build_codex_command`) are cleaned up and tests/usage updated
accordingly.
In `@examples/experimental/cursor_agent_adapter/pyproject.toml`:
- Around line 27-44: Add the missing example registration: update the root
pyproject.toml to include "nat_cursor_agent_adapter" in the top-level examples =
[...] list, and add a corresponding entry under [tool.uv.sources] named
nat_cursor_agent_adapter that maps the package name to the example package
(using editable = true) so the nat_cursor_agent_adapter component and its
entry-point (nat_cursor_agent_adapter = "nat_cursor_agent_adapter.register") are
discoverable and installable.
In `@examples/experimental/cursor_agent_adapter/README.md`:
- Line 150: The phrase "Relay's raw event file" in README.md uses a possessive
's on an inanimate object; update the sentence to use a non-possessive form such
as "the raw Relay event file" (or "Relay raw event file") so the documentation
follows the guideline against using possessive 's with inanimate objects; search
for the exact string "Relay's raw event file" and replace it accordingly in the
README.md content.
In `@examples/experimental/hermes_agent_adapter/configs/config-relay.yml`:
- Around line 4-11: The config currently enables relay (workflow._type:
hermes_agent, relay_enabled: true) but does not set relay_atof_output_dir, so
ATOF events are written to a temp dir and removed; update the config to set
relay_atof_output_dir to the README's inspect path (e.g.
.tmp/nat-relay-hermes-atof) so the events.jsonl file is preserved for the `cat
./.tmp/nat-relay-hermes-atof/events.jsonl` step, or alternatively change the
README to point to the phoenix config that already sets relay_atof_output_dir.
In `@examples/experimental/hermes_agent_adapter/pyproject.toml`:
- Around line 27-44: The root pyproject.toml must include the example module and
a uv source for nat_hermes_agent_adapter; add "nat_hermes_agent_adapter" to the
root examples array and add a [tool.uv.sources] entry mapping
nat_hermes_agent_adapter to the examples/experimental/hermes_agent_adapter path
(editable true) so the project name nat_hermes_agent_adapter and its existing
[tool.uv.sources] usage in the example match the root config.
In `@examples/experimental/hermes_agent_adapter/README.md`:
- Line 126: The sentence "You can inspect Relay's raw event file:" uses a
possessive 's with an inanimate object; update the README line that currently
reads "You can inspect Relay's raw event file:" (search for that exact string)
to a non-possessive phrasing such as "You can inspect the raw event file of
Relay:" or "You can inspect the Relay raw event file:" to comply with the
documentation guideline.
In
`@examples/experimental/openclaw_agent_adapter/src/nat_openclaw_agent_adapter/register.py`:
- Around line 273-274: The public workflow function openclaw_agent (decorated
with `@register_function` and accepting config: OpenClawAgentWorkflowConfig and
_builder: Builder) must include a return type hint and a Google-style docstring;
update the signature to add the appropriate return type (e.g., ->
YourReturnType) and add a docstring immediately below the def that documents
Args (config, _builder) and Returns (describe return value and type), mentioning
any side effects or exceptions as needed so the function complies with public
API guidelines.
In `@packages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.py`:
- Around line 52-63: The loader load_atof_jsonl currently calls json.loads on
every non-empty line and will raise on a malformed line; change it to open the
file with encoding="utf-8" and wrap the json.loads call in a try/except (catch
json.JSONDecodeError/ValueError) so malformed lines are skipped (optionally log
or count them) and valid dict events continue to be appended to the events list;
keep the function signature and return type the same and only alter the file
open call and the per-line parsing logic in load_atof_jsonl.
---
Nitpick comments:
In
`@examples/experimental/claude_code_agent_adapter/src/nat_claude_code_agent_adapter/register.py`:
- Around line 376-379: The current routing makes the CLI path unreachable unless
config.relay_enabled is true, leaving the else branch in _run_claude_code_cli
and parts of the FileNotFoundError message unused; either remove the dead CLI
fallback code (drop the else branch in _run_claude_code_cli and related
non-relay FileNotFoundError text) or add a clear CLI fallback path by updating
_run_claude_code to call _run_claude_code_cli when relay is disabled (or when a
new config flag indicates CLI mode), and ensure _build_claude_command is invoked
only in the supported branch; modify the logic in _run_claude_code,
_run_claude_code_cli, and any FileNotFoundError messaging accordingly so there
is no dead-code path left.
In `@examples/experimental/openclaw_agent_adapter/README.md`:
- Line 58: Replace possessive "'s" usages with "of" phrasing for inanimate
nouns: change "OpenClaw's plugin system" to "the plugin system of OpenClaw" and
"the example's ..." to "the example settings" (or "settings of the example") in
the README content; search for and update any other occurrences of possessive
"'s" applied to inanimate objects so documentation follows the style guideline.
In `@packages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.py`:
- Around line 66-83: The docstring for relay_events_to_intermediate_steps uses
NumPy-style Parameters/---------- formatting; update it to a Google-style
docstring: replace the Parameters section with an Args: block listing events,
root_parent_id, and function_ancestry (each with a one-line description and
types where helpful), and keep the brief top description and Returns/Examples if
present in Google style; ensure the function name
relay_events_to_intermediate_steps and parameter names root_parent_id and
function_ancestry are referenced exactly as in the signature.
In
`@packages/nvidia_nat_core/tests/nat/experimental/test_relay_telemetry_bridge.py`:
- Around line 124-145: Add a negative-path test that writes a JSONL file
containing both a valid event and a malformed/partial line, then call
load_atof_jsonl and inject_atof_jsonl to verify the loader skips the bad line
and only returns/injects the valid event: create a file with one well-formed
event JSON and one broken line, assert load_atof_jsonl(path) returns only the
valid event, subscribe to Context.intermediate_step_manager, call
inject_atof_jsonl(path, context=...), and assert the captured
IntermediateStep(s) correspond only to the valid event (check event types,
parent_id, and count).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 7ef97f18-5301-4c0a-a9da-a9545b40d66b
⛔ Files ignored due to path filters (10)
docs/source/_static/claude_code_agent_adapter/phoenix-relay-trace.pngis excluded by!**/*.pngdocs/source/_static/codex_agent_adapter/phoenix-relay-trace.pngis excluded by!**/*.pngdocs/source/_static/cursor_agent_adapter/phoenix-relay-trace.pngis excluded by!**/*.pngdocs/source/_static/hermes_agent_adapter/phoenix-relay-trace.pngis excluded by!**/*.pngexamples/experimental/claude_code_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/codex_agent_adapter/package-lock.jsonis excluded by!**/package-lock.jsonexamples/experimental/codex_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/cursor_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/hermes_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/openclaw_agent_adapter/uv.lockis excluded by!**/*.lock
📒 Files selected for processing (46)
.gitignoreexamples/README.mdexamples/experimental/claude_code_agent_adapter/README.mdexamples/experimental/claude_code_agent_adapter/configs/config-relay-phoenix-eval.ymlexamples/experimental/claude_code_agent_adapter/configs/config-relay-phoenix.ymlexamples/experimental/claude_code_agent_adapter/configs/config-relay.ymlexamples/experimental/claude_code_agent_adapter/data/eval-smoke.jsonexamples/experimental/claude_code_agent_adapter/pyproject.tomlexamples/experimental/claude_code_agent_adapter/src/nat_claude_code_agent_adapter/__init__.pyexamples/experimental/claude_code_agent_adapter/src/nat_claude_code_agent_adapter/register.pyexamples/experimental/codex_agent_adapter/README.mdexamples/experimental/codex_agent_adapter/configs/config-relay-phoenix-eval.ymlexamples/experimental/codex_agent_adapter/configs/config-relay-phoenix.ymlexamples/experimental/codex_agent_adapter/configs/config-relay.ymlexamples/experimental/codex_agent_adapter/data/eval-smoke.jsonexamples/experimental/codex_agent_adapter/package.jsonexamples/experimental/codex_agent_adapter/pyproject.tomlexamples/experimental/codex_agent_adapter/src/nat_codex_agent_adapter/__init__.pyexamples/experimental/codex_agent_adapter/src/nat_codex_agent_adapter/codex_sdk_runner.mjsexamples/experimental/codex_agent_adapter/src/nat_codex_agent_adapter/register.pyexamples/experimental/cursor_agent_adapter/README.mdexamples/experimental/cursor_agent_adapter/configs/config-relay-phoenix-eval.ymlexamples/experimental/cursor_agent_adapter/configs/config-relay-phoenix.ymlexamples/experimental/cursor_agent_adapter/configs/config-relay.ymlexamples/experimental/cursor_agent_adapter/data/eval-smoke.jsonexamples/experimental/cursor_agent_adapter/pyproject.tomlexamples/experimental/cursor_agent_adapter/src/nat_cursor_agent_adapter/__init__.pyexamples/experimental/cursor_agent_adapter/src/nat_cursor_agent_adapter/register.pyexamples/experimental/hermes_agent_adapter/README.mdexamples/experimental/hermes_agent_adapter/configs/config-relay-phoenix-eval.ymlexamples/experimental/hermes_agent_adapter/configs/config-relay-phoenix.ymlexamples/experimental/hermes_agent_adapter/configs/config-relay.ymlexamples/experimental/hermes_agent_adapter/data/eval-smoke.jsonexamples/experimental/hermes_agent_adapter/pyproject.tomlexamples/experimental/hermes_agent_adapter/src/nat_hermes_agent_adapter/__init__.pyexamples/experimental/hermes_agent_adapter/src/nat_hermes_agent_adapter/register.pyexamples/experimental/openclaw_agent_adapter/README.mdexamples/experimental/openclaw_agent_adapter/configs/config-relay-phoenix-eval.ymlexamples/experimental/openclaw_agent_adapter/configs/config-relay-phoenix.ymlexamples/experimental/openclaw_agent_adapter/configs/config-relay.ymlexamples/experimental/openclaw_agent_adapter/data/eval-smoke.jsonexamples/experimental/openclaw_agent_adapter/pyproject.tomlexamples/experimental/openclaw_agent_adapter/src/nat_openclaw_agent_adapter/__init__.pyexamples/experimental/openclaw_agent_adapter/src/nat_openclaw_agent_adapter/register.pypackages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.pypackages/nvidia_nat_core/tests/nat/experimental/test_relay_telemetry_bridge.py
Signed-off-by: Yuchen Zhang <yuchenz@nvidia.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
pyproject.toml (1)
129-180:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMissing OpenClaw root wiring in
examplesandtool.uv.sources.The new adapter set is incomplete here:
nat_openclaw_agent_adapteris missing from both the top-levelexampleslist and[tool.uv.sources], even though the experimental examples index includes OpenClaw. This can leave one adapter undiscoverable via the same root example install flow as the others.Suggested patch
[tool.setuptools_dynamic_dependencies.optional-dependencies] examples = [ "nat_adk_demo", @@ "nat_multi_frameworks", "nat_notebooks", + "nat_openclaw_agent_adapter", "nat_parallel_executor", @@ [tool.uv.sources] # Examples nat_adk_demo = { path = "examples/frameworks/adk_demo", editable = true } @@ nat_multi_frameworks = { path = "examples/frameworks/multi_frameworks", editable = true } nat_notebooks = { path = "examples/notebooks", editable = true } +nat_openclaw_agent_adapter = { path = "examples/experimental/openclaw_agent_adapter", editable = true } nat_parallel_executor = { path = "examples/control_flow/parallel_executor", editable = true }Also applies to: 233-322
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pyproject.toml` around lines 129 - 180, The examples and UV source roots are missing the new OpenClaw adapter; add "nat_openclaw_agent_adapter" to the top-level examples array (the examples list shown) and also add the corresponding "nat_openclaw_agent_adapter" entry under the [tool.uv.sources] section so the adapter is discoverable via the same root/example install flow as the other adapters.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@pyproject.toml`:
- Around line 129-180: The examples and UV source roots are missing the new
OpenClaw adapter; add "nat_openclaw_agent_adapter" to the top-level examples
array (the examples list shown) and also add the corresponding
"nat_openclaw_agent_adapter" entry under the [tool.uv.sources] section so the
adapter is discoverable via the same root/example install flow as the other
adapters.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: bc3e34aa-91fa-4f1d-86e8-e048ac3da75e
⛔ Files ignored due to path filters (6)
examples/experimental/claude_code_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/codex_agent_adapter/package-lock.jsonis excluded by!**/package-lock.jsonexamples/experimental/codex_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/cursor_agent_adapter/uv.lockis excluded by!**/*.lockexamples/experimental/hermes_agent_adapter/uv.lockis excluded by!**/*.lockuv.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
examples/experimental/codex_agent_adapter/package.jsonexamples/experimental/codex_agent_adapter/src/nat_codex_agent_adapter/register.pyexamples/experimental/cursor_agent_adapter/README.mdexamples/experimental/hermes_agent_adapter/README.mdexamples/experimental/hermes_agent_adapter/configs/config-relay.ymlexamples/experimental/openclaw_agent_adapter/src/nat_openclaw_agent_adapter/register.pypackages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.pypackages/nvidia_nat_core/tests/nat/experimental/test_relay_telemetry_bridge.pypyproject.toml
✅ Files skipped from review due to trivial changes (2)
- examples/experimental/cursor_agent_adapter/README.md
- examples/experimental/hermes_agent_adapter/README.md
🚧 Files skipped from review as they are similar to previous changes (4)
- examples/experimental/codex_agent_adapter/package.json
- examples/experimental/hermes_agent_adapter/configs/config-relay.yml
- examples/experimental/openclaw_agent_adapter/src/nat_openclaw_agent_adapter/register.py
- packages/nvidia_nat_core/src/nat/experimental/relay_telemetry_bridge.py
Description
Adds experimental NVIDIA NeMo Agent Toolkit workflow adapters for five coding-agent harnesses:
Each adapter is packaged as an installable example with a
nat.componentsentry point, a primitive workflow_type, Relay-enabled configs, Phoenix tracing configs, smoke eval configs, and README guidance.This also adds an experimental Relay telemetry bridge used by the Relay-backed adapters, plus Phoenix trace screenshots for the verified workflows.
By Submitting this PR I confirm:
Summary by CodeRabbit
New Features
Documentation
Tests
Chores