This is an automated email from the ASF dual-hosted git repository.

shreemaanabhishek 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 99a079258 chore: rectify business logic/code in ai-proxy (#12055)
99a079258 is described below

commit 99a079258d39879bb7fe371d8265d9a4056938f1
Author: Shreemaan Abhishek <[email protected]>
AuthorDate: Mon Mar 17 19:29:37 2025 +0545

    chore: rectify business logic/code in ai-proxy (#12055)
---
 apisix/init.lua                             |  6 ++++++
 apisix/plugins/ai-drivers/openai-base.lua   | 22 ++++++++++++++-------
 apisix/plugins/ai-proxy-multi.lua           |  1 +
 apisix/plugins/ai-proxy.lua                 |  1 +
 apisix/plugins/ai-proxy/base.lua            |  5 ++++-
 apisix/plugins/ai-proxy/schema.lua          |  4 +---
 t/plugin/ai-proxy-multi.balancer.t          | 12 ------------
 t/plugin/ai-proxy-multi.openai-compatible.t | 12 ------------
 t/plugin/ai-proxy-multi.t                   | 30 -----------------------------
 t/plugin/ai-proxy-multi2.t                  | 18 -----------------
 t/plugin/ai-proxy.openai-compatible.t       | 18 -----------------
 t/plugin/ai-proxy.t                         | 30 -----------------------------
 t/plugin/ai-proxy2.t                        | 18 -----------------
 13 files changed, 28 insertions(+), 149 deletions(-)

diff --git a/apisix/init.lua b/apisix/init.lua
index 4b2ad17e1..426f7fd71 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -453,6 +453,12 @@ end
 
 
 function _M.handle_upstream(api_ctx, route, enable_websocket)
+    -- some plugins(ai-proxy...) request upstream by http client directly
+    if api_ctx.bypass_nginx_upstream then
+        common_phase("before_proxy")
+        return
+    end
+
     local up_id = route.value.upstream_id
 
     -- used for the traffic-split plugin
diff --git a/apisix/plugins/ai-drivers/openai-base.lua 
b/apisix/plugins/ai-drivers/openai-base.lua
index 4f0b38afe..a34261202 100644
--- a/apisix/plugins/ai-drivers/openai-base.lua
+++ b/apisix/plugins/ai-drivers/openai-base.lua
@@ -141,22 +141,25 @@ end
 function _M.read_response(ctx, res)
     local body_reader = res.body_reader
     if not body_reader then
-        core.log.error("AI service sent no response body")
+        core.log.warn("AI service sent no response body")
         return 500
     end
 
     local content_type = res.headers["Content-Type"]
     core.response.set_header("Content-Type", content_type)
 
-    if core.string.find(content_type, "text/event-stream") then
+    if content_type and core.string.find(content_type, "text/event-stream") 
then
         while true do
             local chunk, err = body_reader() -- will read chunk by chunk
             if err then
-                core.log.error("failed to read response chunk: ", err)
-                break
+                core.log.warn("failed to read response chunk: ", err)
+                if core.string.find(err, "timeout") then
+                    return 504
+                end
+                return 500
             end
             if not chunk then
-                break
+                return
             end
 
             ngx_print(chunk)
@@ -192,6 +195,8 @@ function _M.read_response(ctx, res)
 
                 -- usage field is null for non-last events, null is parsed as 
userdata type
                 if data and data.usage and type(data.usage) ~= "userdata" then
+                    core.log.info("got token usage from ai service: ",
+                                        core.json.delay_encode(data.usage))
                     ctx.ai_token_usage = {
                         prompt_tokens = data.usage.prompt_tokens or 0,
                         completion_tokens = data.usage.completion_tokens or 0,
@@ -202,12 +207,14 @@ function _M.read_response(ctx, res)
 
             ::CONTINUE::
         end
-        return
     end
 
     local raw_res_body, err = res:read_body()
     if not raw_res_body then
-        core.log.error("failed to read response body: ", err)
+        core.log.warn("failed to read response body: ", err)
+        if core.string.find(err, "timeout") then
+            return 504
+        end
         return 500
     end
     local res_body, err = core.json.decode(raw_res_body)
@@ -215,6 +222,7 @@ function _M.read_response(ctx, res)
         core.log.warn("invalid response body from ai service: ", raw_res_body, 
" err: ", err,
             ", it will cause token usage not available")
     else
+        core.log.info("got token usage from ai service: ", 
core.json.delay_encode(res_body.usage))
         ctx.ai_token_usage = {
             prompt_tokens = res_body.usage and res_body.usage.prompt_tokens or 
0,
             completion_tokens = res_body.usage and 
res_body.usage.completion_tokens or 0,
diff --git a/apisix/plugins/ai-proxy-multi.lua 
b/apisix/plugins/ai-proxy-multi.lua
index 6065dd3ea..7ac8bb206 100644
--- a/apisix/plugins/ai-proxy-multi.lua
+++ b/apisix/plugins/ai-proxy-multi.lua
@@ -217,6 +217,7 @@ function _M.access(conf, ctx)
     end
     ctx.picked_ai_instance_name = name
     ctx.picked_ai_instance = ai_instance
+    ctx.bypass_nginx_upstream = true
 end
 
 
diff --git a/apisix/plugins/ai-proxy.lua b/apisix/plugins/ai-proxy.lua
index 2301a65e6..fa7f5f24b 100644
--- a/apisix/plugins/ai-proxy.lua
+++ b/apisix/plugins/ai-proxy.lua
@@ -47,6 +47,7 @@ end
 function _M.access(conf, ctx)
     ctx.picked_ai_instance_name = "ai-proxy"
     ctx.picked_ai_instance = conf
+    ctx.bypass_nginx_upstream = true
 end
 
 
diff --git a/apisix/plugins/ai-proxy/base.lua b/apisix/plugins/ai-proxy/base.lua
index d8f1a8944..73c683c0a 100644
--- a/apisix/plugins/ai-proxy/base.lua
+++ b/apisix/plugins/ai-proxy/base.lua
@@ -46,7 +46,10 @@ function _M.before_proxy(conf, ctx)
 
     local res, err = ai_driver:request(conf, request_body, extra_opts)
     if not res then
-        core.log.error("failed to send request to AI service: ", err)
+        core.log.warn("failed to send request to AI service: ", err)
+        if core.string.find(err, "timeout") then
+            return 504
+        end
         return internal_server_error
     end
 
diff --git a/apisix/plugins/ai-proxy/schema.lua 
b/apisix/plugins/ai-proxy/schema.lua
index a2c41b97b..1b9d07b1c 100644
--- a/apisix/plugins/ai-proxy/schema.lua
+++ b/apisix/plugins/ai-proxy/schema.lua
@@ -120,7 +120,7 @@ local ai_instance_schema = {
                 },
             },
         },
-        required = {"name", "provider", "auth"}
+        required = {"name", "provider", "auth", "weight"}
     },
 }
 
@@ -139,7 +139,6 @@ _M.ai_proxy_schema = {
         timeout = {
             type = "integer",
             minimum = 1,
-            maximum = 60000,
             default = 30000,
             description = "timeout in milliseconds",
         },
@@ -196,7 +195,6 @@ _M.ai_proxy_multi_schema = {
         timeout = {
             type = "integer",
             minimum = 1,
-            maximum = 60000,
             default = 30000,
             description = "timeout in milliseconds",
         },
diff --git a/t/plugin/ai-proxy-multi.balancer.t 
b/t/plugin/ai-proxy-multi.balancer.t
index 09076e4a8..48ab5d8ca 100644
--- a/t/plugin/ai-proxy-multi.balancer.t
+++ b/t/plugin/ai-proxy-multi.balancer.t
@@ -198,12 +198,6 @@ __DATA__
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -308,12 +302,6 @@ 
deepseek.deepseek.openai.openai.openai.openai.openai.openai.openai.openai
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
diff --git a/t/plugin/ai-proxy-multi.openai-compatible.t 
b/t/plugin/ai-proxy-multi.openai-compatible.t
index 923c12d37..d5be5d204 100644
--- a/t/plugin/ai-proxy-multi.openai-compatible.t
+++ b/t/plugin/ai-proxy-multi.openai-compatible.t
@@ -160,12 +160,6 @@ __DATA__
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -227,12 +221,6 @@ qr/\{ "content": "1 \+ 1 = 2\.", "role": "assistant" \}/
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
diff --git a/t/plugin/ai-proxy-multi.t b/t/plugin/ai-proxy-multi.t
index 0da04c9de..a70392e60 100644
--- a/t/plugin/ai-proxy-multi.t
+++ b/t/plugin/ai-proxy-multi.t
@@ -230,12 +230,6 @@ qr/.*property "provider" validation failed: matches none 
of the enum values*/
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -294,12 +288,6 @@ Unauthorized
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -417,12 +405,6 @@ request format doesn't match schema: property "messages" 
is required
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
@@ -492,12 +474,6 @@ options_works
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
@@ -567,12 +543,6 @@ path override works
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
diff --git a/t/plugin/ai-proxy-multi2.t b/t/plugin/ai-proxy-multi2.t
index c54e7a67e..536c98c7d 100644
--- a/t/plugin/ai-proxy-multi2.t
+++ b/t/plugin/ai-proxy-multi2.t
@@ -145,12 +145,6 @@ __DATA__
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
@@ -209,12 +203,6 @@ Unauthorized
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
@@ -333,12 +321,6 @@ POST /anything
                             ],
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                  }]]
             )
diff --git a/t/plugin/ai-proxy.openai-compatible.t 
b/t/plugin/ai-proxy.openai-compatible.t
index 84ae175da..a5147648c 100644
--- a/t/plugin/ai-proxy.openai-compatible.t
+++ b/t/plugin/ai-proxy.openai-compatible.t
@@ -148,12 +148,6 @@ __DATA__
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -208,12 +202,6 @@ qr/\{ "content": "1 \+ 1 = 2\.", "role": "assistant" \}/
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -277,12 +265,6 @@ path override works
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
diff --git a/t/plugin/ai-proxy.t b/t/plugin/ai-proxy.t
index 08220fc3c..c5696a2fb 100644
--- a/t/plugin/ai-proxy.t
+++ b/t/plugin/ai-proxy.t
@@ -206,12 +206,6 @@ qr/.*property "provider" validation failed: matches none 
of the enum values.*/
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -264,12 +258,6 @@ Unauthorized
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -381,12 +369,6 @@ request format doesn't match schema: property "messages" 
is required
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -450,12 +432,6 @@ options_works
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -519,12 +495,6 @@ path override works
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
diff --git a/t/plugin/ai-proxy2.t b/t/plugin/ai-proxy2.t
index 942f449cd..43cdd3008 100644
--- a/t/plugin/ai-proxy2.t
+++ b/t/plugin/ai-proxy2.t
@@ -133,12 +133,6 @@ __DATA__
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -191,12 +185,6 @@ Unauthorized
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )
@@ -301,12 +289,6 @@ POST /anything
                             },
                             "ssl_verify": false
                         }
-                    },
-                    "upstream": {
-                        "type": "roundrobin",
-                        "nodes": {
-                            "canbeanything.com": 1
-                        }
                     }
                 }]]
             )

Reply via email to