Skip to content

Conversation

@moznion
Copy link
Contributor

@moznion moznion commented Jun 30, 2025

Background

In the existing implementation, when the response body of streaming events such as Server-Sent Events passes through Committee::Middleware::ResponseValidation, the response_validate method from OpenAPI 3 (or HyperSchema) blocks until the entire body is read. As a result, it was not possible to return responses as streams.

As a workaround for this issue, the one of the solutions is to use a middleware wrapper like the below to completely skip validation for the corresponding endpoint.

class ConditionalCommitteeResponseValidator
  def initialize(app, options = {})
    @app = app
    @middleware = Committee::Middleware::ResponseValidation.new(app, options)
  end

  def call(env)
    path_info = env['PATH_INFO']

    return @app.call(env) if path_info == '/events/stream'

    @middleware.call(env)
  end
end

Features Added by This Patch

This patch adds an option called streaming_content_parsers to Committee::Middleware::ResponseValidation. This option accepts a hash where the key is a Content-Type and the value is a Proc that receives and transforms the response body of that Content-Type.

Content-Types specified via this option bypass the normal path (which waits for the entire body to be read) and instead go through a path via Rack::BodyProxy. This allows the response to be streamed to the client without blocking, while still enabling validation to be performed on the transformed body via the Proc once the response body is closed.

Usage Example

use Committee::Middleware::ResponseValidation,
  schema_path: 'docs/schema.json',
  streaming_content_parsers: {
    'text/event-stream' => ->(body) { body },  # Pass through SSE as string
    'application/x-json-stream' => ->(body) { JSON.parse(body) }  # Parse custom JSON stream
  }

Limitations

For limitations of this feature, please refer to the README.

…` option

Signed-off-by: moznion <moznion@mail.moznion.net>
Copy link
Member

@geemus geemus left a comment

Choose a reason for hiding this comment

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

Looking good overall, added a couple questions to discuss, and I think this looks pretty close already. Thanks!

@moznion moznion requested a review from geemus July 7, 2025 01:45
…tion” section.

Signed-off-by: moznion <moznion@mail.moznion.net>
Copy link
Member

@geemus geemus left a comment

Choose a reason for hiding this comment

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

LGTM, sorry it took me so long to get back to it, July ended up being surprisingly hectic.

@geemus geemus merged commit 0621c14 into interagent:master Aug 2, 2025
8 checks passed
@geemus
Copy link
Member

geemus commented Aug 2, 2025

@moznion did you need a release with this?

@moznion
Copy link
Contributor Author

moznion commented Aug 4, 2025

@geemus
I deeply appreciate your support!
Since it’s not urgent, please feel free to prioritize any scheduled release items.

@moznion moznion deleted the streamingg_support branch August 4, 2025 01:32
@geemus
Copy link
Member

geemus commented Aug 7, 2025

@moznion This has been released as part of v5.5.5. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants