Skip to content

fix: bound AI request and stream payloads - #2539

Merged
lizhimins merged 1 commit into
apache:rocketmq-studiofrom
tju-yxq:codex/bound-ai-payloads
Aug 25, 2026
Merged

fix: bound AI request and stream payloads#2539
lizhimins merged 1 commit into
apache:rocketmq-studiofrom
tju-yxq:codex/bound-ai-payloads

Conversation

@tju-yxq

@tju-yxq tju-yxq commented Aug 22, 2026

Copy link
Copy Markdown

Summary

  • add one UTF-8 byte-budget guard for chat messages, command fields/context, tool invocations, selectors, identifiers, and outbound provider/CLI prompts
  • reject oversized values before gateway, tool registry, HTTP provider, or CLI execution with stable request error semantics
  • apply the existing 5 MiB provider response budget to successful SSE streams, not only non-streaming bodies and streaming error responses
  • validate the effective configured model when no per-request override is present

Why

Successful OpenAI-compatible SSE responses currently use an unbounded input stream, while every other provider/CLI response path is capped. AI request DTOs and structured tool inputs also have no centralized size checks before serialization or process/provider execution. This makes the streaming path inconsistent and lets a single request or provider response retain unnecessarily large payloads.

Implementation notes

  • text limits are measured in UTF-8 bytes and stop counting as soon as the limit is exceeded
  • structured context/tool limits use their serialized JSON size
  • a limited stream reads at most one byte beyond the response budget before raising llm.provider.response_too_large
  • payloads at the configured boundary remain accepted

Tests

  • focused AI package suite: 106 tests passed
  • full backend suite: 1,561 tests passed
  • Checkstyle: 0 violations
  • git diff --check: passed

Production changes: 237 additions / 5 deletions. The size comes from the central guard and bounded SSE implementation, not test padding.

Closes #2538

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary

This PR adds defense-in-depth payload size validation for the RocketMQ Studio AI subsystem. A new AiPayloadGuard class validates UTF-8 byte budgets for user-controlled AI payloads (chat messages, context, tool inputs, outbound prompts) before they reach the LLM gateway, CLI execution, or tool registry. The implementation is thorough, well-tested, and follows existing error handling patterns.

Review Highlights

  • Correctness: UTF-8 byte counting handles surrogate pairs correctly, with proper early exit when limits are exceeded. LimitedInputStream correctly detects limit crossing by reading one extra byte.
  • Security: Validates at all entry points (chat, command, tool, outbound) with clear error codes (llm.request.payload_too_large, llm.provider.response_too_large).
  • Tests: Excellent coverage including boundary conditions, multi-byte character handling, and verification that oversized payloads are rejected before calling upstream.
  • Design: Package-private AiPayloadGuard with static methods is appropriate for a utility class. The inconsistency between chat() (throws) and execute() (returns result) is intentional and documented by the different return types.

Minor Observations

  • CliAgentProvider.complete() validates before checking available() — this is fine since the 400 error is more specific than a 503.
  • The exceedsUtf8Limit() comment about unpaired surrogates being replaced with '?' by the JDK encoder is accurate.

Overall, this is a solid security improvement that prevents potential resource exhaustion from oversized AI payloads.


Automated review by github-manager-bot

@lizhimins
lizhimins force-pushed the codex/bound-ai-payloads branch from f7ed315 to 8a99278 Compare August 25, 2026 09:27
@lizhimins
lizhimins merged commit 7ef2ec7 into apache:rocketmq-studio Aug 25, 2026
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.

3 participants