shreemaan-abhishek opened a new pull request, #13735:
URL: https://github.com/apache/apisix/pull/13735

   ### Description
   
   `ai-aws-content-moderation` only moderated requests, while its sibling 
`ai-aliyun-content-moderation` moderates both directions. AWS Comprehend 
`DetectToxicContent` scores response text just as well, so this was a plugin 
gap rather than an API limitation. It builds on #13647, which moved the plugin 
to the `access` phase with protocol-aware content extraction.
   
   **What changed** — a new `check_response` option plus a `lua_body_filter`:
   
   | Case | Behavior |
   |---|---|
   | non-streaming (`ai_chat`) | the assembled completion is moderated in one 
call; a hit returns `deny_code` with a provider-compatible refusal body |
   | streaming, `stream_check_mode: realtime` | batches are moderated as they 
arrive, bounded by `stream_check_cache_size` (chars) and 
`stream_check_interval` (seconds); a hit replaces the rest of the stream with 
the refusal |
   | streaming, `stream_check_mode: final_packet` (default) | the assembled 
response is moderated once and the last chunk's SSE data events are annotated 
with `risk_level` |
   
   New schema fields: `check_response` (default `false`), `stream_check_mode` 
(default `final_packet`), `stream_check_cache_size` (default `128`), 
`stream_check_interval` (default `3`). All default to the previous behavior, so 
existing configurations are unaffected.
   
   The verdict is published on `ctx.var.llm_content_risk_level` as `high` or 
`none`. Comprehend grades nothing, it only scores against the configured 
thresholds, so the verdict is binary; reusing the same ctx var the aliyun 
plugin sets keeps logging and downstream consumers uniform.
   
   Deny reasons now name the side that tripped (`request body exceeds ...` / 
`response body exceeds ...`).
   
   A Comprehend failure on the **response** side is logged and the content 
passes through: once bytes are on the wire there is no fail-closed option, and 
buffered responses behave the same way for consistency. This matches 
`ai-aliyun-content-moderation`. The request side is unchanged and still fails 
closed with a 500.
   
   **Tests** — `t/plugin/ai-aws-content-moderation.t` TEST 18-30 cover 
non-streaming deny and pass-through, the provider-compatible deny body with a 
custom `deny_message` at the default `deny_code`, `check_response` off leaving 
a toxic response untouched, `final_packet` annotation, `realtime` cutting the 
stream off mid-flight, the upstream-error skip, and schema validation of the 
new fields. New fixtures live under `t/fixtures/aws/`. The Comprehend mock 
gained a fallback for free-form response text, since response content is not a 
fixture key; exact-key lookup still runs first, so every existing test is 
unchanged.
   
   **Docs** — `docs/en/latest/plugins/ai-aws-content-moderation.md` updated 
with the new attributes and the response-moderation description.
   
   # Checklist
   
   - [x] I have explained the need for this PR and the problem it solves
   - [x] I have explained the changes or the new features added to this PR
   - [x] I have added tests corresponding to this change
   - [x] I have updated the documentation to reflect this change
   - [x] I have verified that this change is backward compatible (If not, 
please discuss on the [APISIX mailing 
list](https://github.com/apache/apisix/tree/master#community) first)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to