This is an automated email from the ASF dual-hosted git repository.
nic-6443 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 76ff252b1 test(ai-proxy): cover the AWS moderation path in the
truncated-stream suite (#13880)
76ff252b1 is described below
commit 76ff252b13e618b261bb98223f88737cfa7a4136
Author: Nic <[email protected]>
AuthorDate: Wed Aug 26 17:38:38 2026 +0800
test(ai-proxy): cover the AWS moderation path in the truncated-stream suite
(#13880)
---
t/lib/truncated_sse.lua | 28 +++++++++++++++
t/plugin/ai-proxy-stream-truncated.t | 69 ++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+)
diff --git a/t/lib/truncated_sse.lua b/t/lib/truncated_sse.lua
index 3ceec4a67..f1d77b3b8 100644
--- a/t/lib/truncated_sse.lua
+++ b/t/lib/truncated_sse.lua
@@ -111,4 +111,32 @@ function _M.serve_abort_once()
end
+-- Minimal AWS Comprehend detectToxicContent stand-in: answers one clean result
+-- per submitted segment. The truncation tests only need the moderation plugin
to
+-- reach its terminator-synthesis branch, not a particular verdict.
+function _M.serve_clean_comprehend()
+ local json = require("cjson.safe")
+ ngx.req.read_body()
+ local body = json.decode(ngx.req.get_body_data() or "{}") or {}
+ local results = {}
+ for i in ipairs(body.TextSegments or {}) do
+ results[i] = {
+ Toxicity = 0.01,
+ Labels = {
+ { Name = "PROFANITY", Score = 0.01 },
+ { Name = "HATE_SPEECH", Score = 0.01 },
+ { Name = "INSULT", Score = 0.01 },
+ { Name = "GRAPHIC", Score = 0.01 },
+ { Name = "HARASSMENT_OR_ABUSE", Score = 0.01 },
+ { Name = "SEXUAL", Score = 0.01 },
+ { Name = "VIOLENCE_OR_THREAT", Score = 0.01 },
+ },
+ }
+ end
+ ngx.status = 200
+ ngx.header["Content-Type"] = "application/json"
+ ngx.say(json.encode({ ResultList = results }))
+end
+
+
return _M
diff --git a/t/plugin/ai-proxy-stream-truncated.t
b/t/plugin/ai-proxy-stream-truncated.t
index b75934626..5e92f4b50 100644
--- a/t/plugin/ai-proxy-stream-truncated.t
+++ b/t/plugin/ai-proxy-stream-truncated.t
@@ -43,6 +43,7 @@ plugins:
- ai-proxy
- ai-proxy-multi
- ai-aliyun-content-moderation
+ - ai-aws-content-moderation
plugin_attr:
ai-proxy:
http_client: lua-resty-http
@@ -51,7 +52,21 @@ _EOC_
$block->set_value("extra_yaml_config", $user_yaml_config);
}
+ my $main_config = $block->main_config // <<_EOC_;
+ env AWS_REGION=us-east-1;
+_EOC_
+ $block->set_value("main_config", $main_config);
+
my $http_config = $block->http_config // <<_EOC_;
+ server {
+ listen 2668;
+ location / {
+ content_by_lua_block {
+ require("lib.truncated_sse").serve_clean_comprehend()
+ }
+ }
+ }
+
server {
listen 6724;
@@ -373,3 +388,57 @@ qr/^(?!.*message_stop)(?=.*"text":"hello")/s
failed to read response chunk: closed
falling back to
--- timeout: 10
+
+
+
+=== TEST 11: ai-proxy + ai-aws-content-moderation on the usage-then-truncate
upstream
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, [[{
+ "uri": "/truncated",
+ "plugins": {
+ "ai-proxy": {
+ "provider": "openai",
+ "auth": {"header": {"Authorization": "Bearer test"}},
+ "options": {"model": "gpt-4", "stream": true},
+ "override": {
+ "endpoint":
"http://127.0.0.1:6724/v1/chat/completions-usage-then-truncate"
+ },
+ "ssl_verify": false
+ },
+ "ai-aws-content-moderation": {
+ "comprehend": {
+ "access_key_id": "access",
+ "secret_access_key": "ea+secret",
+ "region": "us-east-1",
+ "endpoint": "http://127.0.0.1:2668"
+ },
+ "moderation_categories": {"PROFANITY": 0.5},
+ "check_request": false,
+ "check_response": true,
+ "stream_check_mode": "final_packet"
+ }
+ }
+ }]])
+ if code >= 300 then ngx.status = code end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 12: the AWS moderation path does not terminate a truncated stream
either
+--- request
+POST /truncated
+{"messages":[{"role":"user","content":"hi"}],"model":"gpt-4","stream":true}
+--- response_body_like eval
+# Same assertion as TEST 8, against the second plugin whose terminator
+# synthesis this change gates on ctx.ai_stream_aborted.
+qr/^(?!.*\[DONE\])(?=.*"content":"hello")(?=.*"risk_level":)/s
+--- error_log
+failed to read response chunk: closed
+--- timeout: 10