Skip to content

Implement WireframeProtocol trait integration#151

Merged
leynos merged 4 commits intomainfrom
codex/implement-wireframeprotocol-integration-and-tests
Jun 28, 2025
Merged

Implement WireframeProtocol trait integration#151
leynos merged 4 commits intomainfrom
codex/implement-wireframeprotocol-integration-and-tests

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Jun 28, 2025

Summary

  • implement WireframeProtocol trait with ConnectionContext
  • convert protocol implementations into ProtocolHooks
  • expose trait via WireframeApp::with_protocol
  • pass connection context through ConnectionActor
  • test builder and actor integration using rstest

Testing

  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_686056f891248322a58e136bfc07c812

Summary by Sourcery

Implement WireframeProtocol trait integration by introducing ConnectionContext and deriving protocol hooks for connection lifecycle events. Expose protocol setup in WireframeApp via with_protocol, update ConnectionActor to accept PushHandle and invoke hooks with context, and reinforce the design with updated tests and documentation.

New Features:

  • Introduce WireframeProtocol trait defining on_connection_setup, before_send, and on_command_end hooks.
  • Add ConnectionContext type to carry per-connection state through protocol callbacks.
  • Expose protocol configuration in WireframeApp via with_protocol, protocol, and protocol_hooks methods.

Enhancements:

  • Extend ProtocolHooks to support on_connection_setup and build hooks from a WireframeProtocol implementation.
  • Refactor ProtocolHooks and ConnectionActor to pass ConnectionContext and invoke hooks during setup, frame sending, and command completion.
  • Update ConnectionActor constructor to accept PushHandle and initialize protocol hooks with context.

Documentation:

  • Document WireframeProtocol trait and ProtocolHooks in asynchronous-outbound-messaging-design with a class diagram.

Tests:

  • Revise existing connection_actor tests to supply PushHandle and exercise the new hook logic.
  • Add integration tests for WireframeProtocol implementations validating hook invocation and frame mutation.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Jun 28, 2025

Reviewer's Guide

This PR integrates the new WireframeProtocol trait and per-connection context into the core API: it defines ConnectionContext and the protocol trait, stitches protocol hooks into WireframeApp and ConnectionActor, and updates tests and documentation to verify context-aware callbacks.

Class diagram for WireframeProtocol trait integration

classDiagram
    class WireframeProtocol {
        <<trait>>
        +Frame: FrameLike
        +ProtocolError
        +on_connection_setup(PushHandle<Frame>, &mut ConnectionContext)
        +before_send(&mut Frame, &mut ConnectionContext)
        +on_command_end(&mut ConnectionContext)
    }
    class ProtocolHooks {
        -on_connection_setup: Option<OnConnectionSetupHook<F>>
        -before_send: Option<BeforeSendHook<F>>
        -on_command_end: Option<OnCommandEndHook>
        +on_connection_setup(&mut self, PushHandle<F>, &mut ConnectionContext)
        +before_send(&mut self, &mut F, &mut ConnectionContext)
        +on_command_end(&mut self, &mut ConnectionContext)
        +from_protocol(protocol: Arc<P>)
    }
    class ConnectionContext {
        <<struct>>
    }
    class WireframeApp {
        -protocol: Option<Arc<dyn WireframeProtocol<Frame=Vec<u8>, ProtocolError=()>>>
        +with_protocol(protocol)
        +protocol()
        +protocol_hooks()
    }
    class ConnectionActor {
        -hooks: ProtocolHooks<F>
        -ctx: ConnectionContext
    }
    WireframeApp --> "1" WireframeProtocol : uses
    WireframeApp --> "1" ProtocolHooks : creates
    ProtocolHooks --> "1" WireframeProtocol : from_protocol
    ConnectionActor --> "1" ProtocolHooks : uses
    ConnectionActor --> "1" ConnectionContext : owns
    ProtocolHooks --> "1" ConnectionContext : passes to hooks
    WireframeProtocol --> "1" ConnectionContext : uses
    WireframeProtocol --> "1" PushHandle : uses
    WireframeProtocol <|.. ProtocolHooks : implemented by
Loading

File-Level Changes

Change Details Files
Introduce WireframeProtocol trait and ConnectionContext, and extend ProtocolHooks with context-aware callbacks
  • Add ConnectionContext struct as an extensible per-connection state
  • Define WireframeProtocol trait with on_connection_setup, before_send, on_command_end methods
  • Update hook type aliases to accept &mut ConnectionContext
  • Implement ProtocolHooks methods to pass context and add from_protocol constructor
src/hooks.rs
src/lib.rs
Add protocol registration and retrieval to WireframeApp
  • Introduce protocol field in WireframeApp
  • Implement with_protocol method to install a WireframeProtocol
  • Add protocol() getter and protocol_hooks() to derive hooks or return defaults
src/app.rs
Embed ConnectionContext in ConnectionActor and invoke protocol hooks
  • Modify ConnectionActor.new and with_hooks to accept PushHandle and initialize ConnectionContext
  • Add ctx field to actor state
  • Call on_connection_setup during setup and pass context into before_send and on_command_end
src/connection.rs
Update tests and documentation for protocol integration
  • Adjust existing connection_actor tests to pass handle, drop it after setup, and update hook signatures
  • Add new wireframe_protocol.rs integration tests verifying builder and actor use the trait
  • Extend design doc with a class diagram and notes on ConnectionContext
tests/connection_actor.rs
tests/wireframe_protocol.rs
docs/asynchronous-outbound-messaging-design.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 28, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a formal protocol trait allowing integration of custom protocol implementations with context-aware callbacks.
    • Added support for configuring and accessing protocol implementations and hooks within the application builder.
    • Enabled per-connection context to be passed to protocol hooks for advanced state management.
    • Provided a new class diagram in the documentation to illustrate component relationships.
  • Bug Fixes

    • None.
  • Tests

    • Added comprehensive integration tests for protocol trait usage and its interaction with the application and connection actor.
  • Documentation

    • Enhanced documentation with a Mermaid diagram clarifying the architecture and extension points.
      """

Summary by CodeRabbit

  • New Features

    • Introduced a formal protocol interface allowing custom protocol logic and per-connection context within the application builder.
    • Added new methods to configure and access protocol implementations and hooks in the application.
    • Exported protocol-related types for broader use.
  • Improvements

    • Enhanced protocol hooks to support context-aware callbacks for more flexible connection handling.
    • Updated documentation with clearer diagrams and improved formatting.
  • Tests

    • Added comprehensive tests for protocol integration and context handling in connections and hooks.

Walkthrough

This update introduces a formal WireframeProtocol trait with context-aware hooks, integrates it into the application builder (WireframeApp) and connection actor (ConnectionActor), and updates hook signatures to accept a mutable connection context. Documentation and tests are revised to reflect these changes, with new diagrams and protocol-driven integration tests.

Changes

File(s) Change Summary
docs/asynchronous-outbound-messaging-design.md Added a Mermaid class diagram illustrating the asynchronous outbound messaging design components and their relationships.
src/app.rs Added optional protocol field and methods to set/access a WireframeProtocol and its hooks in WireframeApp.
src/connection.rs Added ctx: ConnectionContext to ConnectionActor; updated hook invocations to pass mutable context.
src/hooks.rs Introduced WireframeProtocol trait, ConnectionContext struct, context-aware callbacks in ProtocolHooks, and builder.
src/lib.rs Re-exported ConnectionContext and WireframeProtocol alongside ProtocolHooks.
tests/connection_actor.rs Updated test hook closures to accept mutable ConnectionContext parameters and consistently pass PushHandle to constructors.
tests/wireframe_protocol.rs Added new integration tests for protocol hooks and protocol-driven connection actor behaviour.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WireframeApp
    participant Protocol (WireframeProtocol)
    participant ConnectionActor
    participant ConnectionContext

    User->>WireframeApp: with_protocol(Protocol)
    WireframeApp->>WireframeApp: Store Arc<Protocol>
    User->>WireframeApp: protocol_hooks()
    WireframeApp->>Protocol: Create ProtocolHooks from Protocol
    User->>ConnectionActor: Construct with ProtocolHooks
    ConnectionActor->>ConnectionContext: Initialise context
    ConnectionActor->>ProtocolHooks: before_send(frame, ctx)
    ProtocolHooks->>Protocol: before_send(frame, ctx)
    Protocol->>ConnectionContext: Mutate context as needed
Loading

Possibly related PRs

Poem

In the warren, code hops anew,
Protocols and hooks—context in view!
Actors connect, with context in tow,
Diagrams align, as the messages flow.
🐇 With every test, the future looks bright—
Wireframe’s protocol hops into the light!
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5bca6d6 and 06abbe8.

📒 Files selected for processing (6)
  • docs/asynchronous-outbound-messaging-design.md (1 hunks)
  • src/app.rs (6 hunks)
  • src/connection.rs (8 hunks)
  • src/hooks.rs (2 hunks)
  • tests/connection_actor.rs (9 hunks)
  • tests/wireframe_protocol.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
`docs/**/*.md`: Use the markdown files within the `docs/` directory as a knowled...

docs/**/*.md: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Proactively update the relevant file(s) in the docs/ directory to reflect the latest state when new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve.
Documentation in the docs/ directory must use en-GB-oxendict spelling and grammar, except for the word 'license'.

📄 Source: CodeRabbit Inference Engine (AGENTS.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`**/*.md`: Validate Markdown files using `markdownlint *.md **/*.md`. Run `mdfor...

**/*.md: Validate Markdown files using markdownlint *.md **/*.md.
Run mdformat-all after any documentation changes to format all Markdown files and fix table markup.
Validate Markdown Mermaid diagrams using the nixie CLI by running nixie *.md **/*.md.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown files must be wrapped at 120 columns.
Tables and headings in Markdown files must not be wrapped.

📄 Source: CodeRabbit Inference Engine (AGENTS.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`docs/*`: Each file in the docs/ directory provides design, roadmap, testing, op...

docs/*: Each file in the docs/ directory provides design, roadmap, testing, operations, or reference documentation for the project. Use these files as a reference for understanding the project's architecture, development plans, testing strategies, operational guidelines, and documentation conventions.

📄 Source: CodeRabbit Inference Engine (docs/contents.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`docs/**/*.md`: Use British English spelling based on the Oxford English Diction...

docs/**/*.md: Use British English spelling based on the Oxford English Dictionary, except retain US spelling in API names (e.g., 'color').
Use the Oxford comma in lists.
Write headings in sentence case and use Markdown heading levels in order without skipping.
Follow markdownlint recommendations for Markdown formatting.
Always use fenced code blocks with a language identifier; use 'plaintext' for non-code text.
Use '-' as the first level bullet and renumber lists when items change.
Prefer inline links using 'text' or angle brackets around the URL.
Expand any uncommon acronym on first use, e.g., Continuous Integration (CI).
Wrap paragraphs at 80 columns, code at 120 columns, and do not wrap tables.
Use footnotes referenced with '[^label]'.
When embedding figures, use 'alt text' and provide concise alt text describing the content.
Add a short description before each Mermaid diagram for screen readers.

📄 Source: CodeRabbit Inference Engine (docs/documentation-style-guide.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`docs/**/*`: Write official documentation for new features, including separate g...

docs/**/*: Write official documentation for new features, including separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each with runnable examples and explanations of relevant concepts and APIs.

📄 Source: CodeRabbit Inference Engine (docs/wireframe-1-0-detailed-development-roadmap.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`**/*.md`: * Avoid 2nd person or 1st person pronouns ("I", "you", "we") * Use en...

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-oxendic spelling and grammar.
  • Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
  • Code blocks should be wrapped to 120 columns.
  • Headings must not be wrapped.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`**/*.rs`: Every Rust module must begin with a module level (`//!`) comment expl...

**/*.rs: Every Rust module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public Rust APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.

📄 Source: CodeRabbit Inference Engine (AGENTS.md)

List of files the instruction was applied to:

  • tests/connection_actor.rs
  • tests/wireframe_protocol.rs
  • src/connection.rs
  • src/app.rs
  • src/hooks.rs
`**/*.rs`: * Seek to keep the cyclomatic complexity of functions no more than 12...

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments must use en-GB-oxendict spelling and grammar.

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • tests/connection_actor.rs
  • tests/wireframe_protocol.rs
  • src/connection.rs
  • src/app.rs
  • src/hooks.rs
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: leynos/wireframe#0
File: docs/asynchronous-outbound-messaging-design.md:0-0
Timestamp: 2025-06-28T09:22:07.295Z
Learning: All protocol-specific logic and callbacks should be encapsulated in a single WireframeProtocol trait, which defines hooks for connection setup, frame mutation before send, and command completion. This trait-based approach is preferred over passing individual closures for extensibility and clarity.
🧬 Code Graph Analysis (2)
tests/connection_actor.rs (2)
src/connection.rs (5)
  • new (86-93)
  • new (391-400)
  • shutdown_token (127-127)
  • default (35-40)
  • with_hooks (97-117)
src/hooks.rs (1)
  • default (59-65)
tests/wireframe_protocol.rs (5)
src/hooks.rs (6)
  • on_connection_setup (29-29)
  • on_connection_setup (70-74)
  • before_send (32-32)
  • before_send (76-80)
  • on_command_end (35-35)
  • on_command_end (83-87)
src/app.rs (4)
  • on_connection_setup (351-368)
  • new (197-197)
  • new (252-252)
  • protocol (406-410)
src/connection.rs (3)
  • new (86-93)
  • new (391-400)
  • with_hooks (97-117)
tests/connection_actor.rs (1)
  • queues (18-18)
src/push.rs (1)
  • bounded (131-145)
🔇 Additional comments (25)
tests/connection_actor.rs (3)

40-40: LGTM: Constructor calls correctly updated for new signature.

The tests properly pass the handle parameter to ConnectionActor::new, which is now required according to the updated constructor signature in src/connection.rs.

Also applies to: 64-64, 79-80, 98-98, 123-123, 155-155


179-179: LGTM: Import correctly expanded for new context type.

The import statement properly includes ConnectionContext to support the updated hook signatures.


192-192: LGTM: Hook signatures correctly updated for context awareness.

The before_send and on_command_end closures now properly accept the ConnectionContext parameter, consistent with the new protocol hook signatures defined in src/hooks.rs.

Also applies to: 220-222

docs/asynchronous-outbound-messaging-design.md (1)

469-513: Excellent architectural documentation with clear component relationships.

The new Mermaid class diagram effectively illustrates the structural design of the protocol integration, showing how WireframeApp uses WireframeProtocol to create ProtocolHooks that are consumed by ConnectionActor. The note about ConnectionContext being intentionally empty provides valuable context for future extensibility.

tests/wireframe_protocol.rs (4)

1-7: LGTM: Module documentation properly addresses coding guidelines.

The module-level documentation correctly explains the purpose and utility of the integration tests, following the requirement that every Rust module must begin with a //! comment.


24-45: Well-designed test protocol implementation.

The TestProtocol implementation correctly uses atomic counters for thread-safe testing and implements all required WireframeProtocol methods with appropriate behaviour for verification. The frame mutation in before_send provides a clear, testable side effect.


47-67: Comprehensive test of protocol hooks generation.

This test properly verifies that WireframeApp::protocol_hooks() produces working hooks that invoke the underlying protocol methods correctly, with proper frame mutation and counter updates.


69-94: Excellent end-to-end integration test.

This test effectively verifies the complete integration flow: protocol installation in the app, hook generation, and proper usage by ConnectionActor during frame processing. The assertions confirm both frame mutations and hook invocations occur as expected.

src/connection.rs (6)

16-16: LGTM: Import correctly expanded for new hook types.

The import statement properly includes ConnectionContext and ProtocolHooks to support the new protocol integration.


62-62: LGTM: Connection context field properly added.

The ctx: ConnectionContext field is correctly added to maintain per-connection state for protocol hooks.


86-93: LGTM: Constructor signature correctly updated.

The new constructor now properly accepts a PushHandle<F> parameter and delegates to with_hooks with default protocol hooks, maintaining backward compatibility whilst supporting the new protocol system.


97-117: Excellent protocol integration in constructor.

The with_hooks constructor properly initialises the connection context and immediately invokes the on_connection_setup hook, ensuring protocol-specific setup occurs when the actor is created. The field initialisation is complete and correct.


217-217: LGTM: Context passed consistently to frame processing hooks.

All before_send hook invocations throughout the frame processing lifecycle (process_high, process_low, after_high, and handle_response) correctly pass the mutable connection context, enabling protocol-aware frame modifications.

Also applies to: 230-230, 283-283, 326-326


332-332: LGTM: Command completion hook properly invoked.

The on_command_end hook is correctly called with the mutable connection context when the response stream completes, allowing protocols to perform cleanup or state updates.

src/app.rs (5)

21-21: LGTM: Import and field correctly added.

The import statement properly includes the new protocol types, and the optional protocol field is correctly added to the WireframeApp struct with appropriate type constraints.

Also applies to: 84-84


240-240: LGTM: Protocol field properly propagated.

The protocol field is correctly initialised to None in the default constructor and properly propagated through all builder methods that create new instances (on_connection_setup and serializer).

Also applies to: 366-366, 448-448


388-400: LGTM: Protocol installation method well-implemented.

The with_protocol method correctly wraps the protocol in an Arc and follows the builder pattern. The documentation clearly explains the method's purpose and the type constraints are appropriate.


402-410: LGTM: Protocol getter correctly implemented.

The protocol method properly returns a cloned Arc using idiomatic Option mapping, with clear documentation explaining the return value.


412-421: LGTM: Protocol hooks generation properly implemented.

The protocol_hooks method correctly derives hooks from the installed protocol using ProtocolHooks::from_protocol and provides appropriate fallback to default hooks when no protocol is installed.

src/hooks.rs (6)

1-7: Module documentation is clear and follows Rust conventions.

The updated documentation properly describes both ProtocolHooks and the new WireframeProtocol trait, providing good context for module users.


8-11: Required imports added correctly.

The new imports support the WireframeProtocol trait and its integration with the push handle mechanism.


19-36: Well-designed trait following best practices.

The WireframeProtocol trait properly encapsulates protocol-specific logic with appropriate bounds and default implementations. The trait aligns with the retrieved learning about consolidating protocol callbacks into a single trait.


38-47: Type aliases consistently updated for context support.

All callback type aliases now properly include the ConnectionContext parameter, maintaining consistency with the trait methods.


50-65: ProtocolHooks struct properly extended.

The new on_connection_setup field is well-documented and correctly initialised in the Default implementation.


69-87: Hook invocation methods correctly handle context.

The methods properly pass the ConnectionContext to callbacks, with on_connection_setup correctly using take() for its one-time execution semantics.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Post Copyable Unit Tests in Comment
  • Commit Unit Tests in branch codex/implement-wireframeprotocol-integration-and-tests

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @leynos - I've reviewed your changes - here's some feedback:

  • ProtocolHooks::from_protocol only wires up before_send and on_command_end—on_connection_setup is never registered or invoked, so you’ll need to add that hook when you create the ConnectionActor.
  • with_protocol is hard-coded to Frame = Vec and ProtocolError = (); if you want to support other frame types or errors, consider making WireframeApp generic over those types instead of fixing them in the API.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- ProtocolHooks::from_protocol only wires up before_send and on_command_end—`on_connection_setup` is never registered or invoked, so you’ll need to add that hook when you create the ConnectionActor.
- with_protocol is hard-coded to Frame = Vec<u8> and ProtocolError = (); if you want to support other frame types or errors, consider making WireframeApp generic over those types instead of fixing them in the API.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5333cfa and 5bca6d6.

📒 Files selected for processing (7)
  • docs/asynchronous-outbound-messaging-design.md (5 hunks)
  • src/app.rs (6 hunks)
  • src/connection.rs (7 hunks)
  • src/hooks.rs (2 hunks)
  • src/lib.rs (1 hunks)
  • tests/connection_actor.rs (3 hunks)
  • tests/wireframe_protocol.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
`**/*.rs`: Every Rust module must begin with a module level (`//!`) comment expl...

**/*.rs: Every Rust module must begin with a module level (//!) comment explaining the module's purpose and utility.
Document public Rust APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.

📄 Source: CodeRabbit Inference Engine (AGENTS.md)

List of files the instruction was applied to:

  • src/lib.rs
  • src/connection.rs
  • tests/wireframe_protocol.rs
  • src/app.rs
  • tests/connection_actor.rs
  • src/hooks.rs
`**/*.rs`: * Seek to keep the cyclomatic complexity of functions no more than 12...

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments must use en-GB-oxendict spelling and grammar.

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • src/lib.rs
  • src/connection.rs
  • tests/wireframe_protocol.rs
  • src/app.rs
  • tests/connection_actor.rs
  • src/hooks.rs
`docs/**/*.md`: Use the markdown files within the `docs/` directory as a knowled...

docs/**/*.md: Use the markdown files within the docs/ directory as a knowledge base and source of truth for project requirements, dependency choices, and architectural decisions.
Proactively update the relevant file(s) in the docs/ directory to reflect the latest state when new decisions are made, requirements change, libraries are added/removed, or architectural patterns evolve.
Documentation in the docs/ directory must use en-GB-oxendict spelling and grammar, except for the word 'license'.

📄 Source: CodeRabbit Inference Engine (AGENTS.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`**/*.md`: Validate Markdown files using `markdownlint *.md **/*.md`. Run `mdfor...

**/*.md: Validate Markdown files using markdownlint *.md **/*.md.
Run mdformat-all after any documentation changes to format all Markdown files and fix table markup.
Validate Markdown Mermaid diagrams using the nixie CLI by running nixie *.md **/*.md.
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown files must be wrapped at 120 columns.
Tables and headings in Markdown files must not be wrapped.

📄 Source: CodeRabbit Inference Engine (AGENTS.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`docs/*`: Each file in the docs/ directory provides design, roadmap, testing, op...

docs/*: Each file in the docs/ directory provides design, roadmap, testing, operations, or reference documentation for the project. Use these files as a reference for understanding the project's architecture, development plans, testing strategies, operational guidelines, and documentation conventions.

📄 Source: CodeRabbit Inference Engine (docs/contents.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`docs/**/*.md`: Use British English spelling based on the Oxford English Diction...

docs/**/*.md: Use British English spelling based on the Oxford English Dictionary, except retain US spelling in API names (e.g., 'color').
Use the Oxford comma in lists.
Write headings in sentence case and use Markdown heading levels in order without skipping.
Follow markdownlint recommendations for Markdown formatting.
Always use fenced code blocks with a language identifier; use 'plaintext' for non-code text.
Use '-' as the first level bullet and renumber lists when items change.
Prefer inline links using 'text' or angle brackets around the URL.
Expand any uncommon acronym on first use, e.g., Continuous Integration (CI).
Wrap paragraphs at 80 columns, code at 120 columns, and do not wrap tables.
Use footnotes referenced with '[^label]'.
When embedding figures, use 'alt text' and provide concise alt text describing the content.
Add a short description before each Mermaid diagram for screen readers.

📄 Source: CodeRabbit Inference Engine (docs/documentation-style-guide.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`docs/**/*`: Write official documentation for new features, including separate g...

docs/**/*: Write official documentation for new features, including separate guides for 'Duplex Messaging & Pushes', 'Streaming Responses', and 'Message Fragmentation', each with runnable examples and explanations of relevant concepts and APIs.

📄 Source: CodeRabbit Inference Engine (docs/wireframe-1-0-detailed-development-roadmap.md)

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
`**/*.md`: * Avoid 2nd person or 1st person pronouns ("I", "you", "we") * Use en...

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-oxendic spelling and grammar.
  • Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
  • Code blocks should be wrapped to 120 columns.
  • Headings must not be wrapped.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • docs/asynchronous-outbound-messaging-design.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: leynos/wireframe#0
File: docs/asynchronous-outbound-messaging-design.md:0-0
Timestamp: 2025-06-28T09:22:07.295Z
Learning: All protocol-specific logic and callbacks should be encapsulated in a single WireframeProtocol trait, which defines hooks for connection setup, frame mutation before send, and command completion. This trait-based approach is preferred over passing individual closures for extensibility and clarity.
🧬 Code Graph Analysis (1)
tests/wireframe_protocol.rs (5)
src/hooks.rs (5)
  • on_connection_setup (26-26)
  • before_send (29-29)
  • before_send (60-64)
  • on_command_end (32-32)
  • on_command_end (67-71)
src/app.rs (4)
  • on_connection_setup (351-368)
  • new (197-197)
  • new (252-252)
  • protocol (400-404)
src/connection.rs (3)
  • new (86-92)
  • new (387-396)
  • with_hooks (96-113)
tests/connection_actor.rs (1)
  • queues (18-18)
src/push.rs (1)
  • bounded (131-145)
🪛 LanguageTool
docs/asynchronous-outbound-messaging-design.md

[uncategorized] ~73-~73: Loose punctuation mark.
Context: ...low_priority_push_rx: mpsc::Receiver`: For standard, non-urgent background ...

(UNLIKELY_OPENING_PUNCTUATION)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-test
🔇 Additional comments (20)
src/lib.rs (1)

23-23: LGTM: Appropriate API exports for the new protocol system.

The addition of ConnectionContext and WireframeProtocol to the public exports correctly exposes the new protocol trait and context APIs introduced in this PR.

tests/connection_actor.rs (3)

181-181: LGTM: Import addition for updated hook signatures.

Correctly adds ConnectionContext import to support the updated hook signatures.


195-195: LGTM: Hook signature updated for context parameter.

The before_send hook closure correctly accepts the new ConnectionContext parameter while preserving the existing test logic.


219-221: LGTM: Hook signature updated for context parameter.

The on_command_end hook closure correctly accepts the new ConnectionContext parameter while preserving the existing test logic.

docs/asynchronous-outbound-messaging-design.md (3)

42-48: LGTM: Table formatting improvements.

The table alignment improvements enhance readability of the design requirements.


73-74: LGTM: Corrected polling order numbering.

The numbering corrections accurately reflect the actual priority order used in the biased select loop.

Also applies to: 93-100


469-508: Excellent architectural documentation.

The new Mermaid class diagram provides valuable visual context for understanding the relationships between WireframeProtocol, ProtocolHooks, ConnectionContext, WireframeApp, and ConnectionActor. This helps developers understand the protocol integration architecture.

src/connection.rs (5)

16-16: LGTM: Appropriate import for ConnectionContext.

Correctly imports ConnectionContext to support the new context-aware hooks.


62-62: LGTM: ConnectionContext field addition.

The ctx field appropriately stores the connection context that will be passed to protocol hooks.


213-213: LGTM: Consistent context parameter passing.

All before_send hook calls correctly pass the mutable context reference, maintaining consistency across the codebase.

Also applies to: 226-226, 279-279, 322-322


328-328: LGTM: Context parameter for command completion.

The on_command_end hook call correctly passes the mutable context reference when a command completes.


108-108: ConnectionContext initialisation pattern confirmed.

  • Defined as a unit struct in src/hooks.rs with #[derive(Default)].
  • Instantiating via ConnectionContext (no parameters) is valid and intended.
tests/wireframe_protocol.rs (3)

17-38: LGTM: Well-designed test protocol implementation.

The TestProtocol struct provides a clean implementation for testing protocol integration, using atomic operations for thread-safe counter tracking and demonstrating frame modification in the before_send hook.


40-56: LGTM: Comprehensive protocol hooks integration test.

This test effectively verifies that WireframeApp correctly generates ProtocolHooks from an installed protocol and that the hooks function properly with context parameters.


58-83: LGTM: End-to-end connection actor integration test.

This test provides excellent coverage of the complete integration flow from app builder through connection actor, verifying that protocol hooks are applied to both pushed frames and streaming responses.

src/app.rs (2)

21-21: Import additions are appropriate.

The import correctly brings in both ProtocolHooks and WireframeProtocol types needed for the new protocol integration functionality.


84-84: Protocol field addition and propagation are well-implemented.

The optional protocol field is properly typed with Arc for shared ownership, correctly initialized to None, and consistently propagated through builder method transformations.

Also applies to: 240-240, 366-366, 440-440

src/hooks.rs (3)

3-10: Module documentation and imports are well-structured.

The updated documentation clearly describes both ProtocolHooks and WireframeProtocol. Imports are minimal and necessary for the implementation.


16-33: The WireframeProtocol trait is excellently designed.

The trait provides a clean abstraction with:

  • Flexible associated types for frame and error handling
  • Default implementations allowing partial adoption
  • Context-aware callbacks for state management
  • PushHandle in setup for asynchronous messaging support

This design aligns perfectly with the architectural goal of encapsulating protocol-specific logic.


36-36: Context-aware callback updates are properly implemented.

The type aliases and methods correctly incorporate ConnectionContext parameters, enabling stateful protocol implementations whilst maintaining clean separation of concerns.

Also applies to: 39-39, 60-70

Comment thread tests/wireframe_protocol.rs
Comment thread src/app.rs
Comment thread src/app.rs
Comment thread src/app.rs
Comment thread src/hooks.rs
Comment thread src/hooks.rs
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jun 28, 2025

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @leynos - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@leynos leynos merged commit af47ccc into main Jun 28, 2025
5 checks passed
@leynos leynos deleted the codex/implement-wireframeprotocol-integration-and-tests branch June 28, 2025 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant