You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by "sihyeonn (via GitHub)" <gi...@apache.org> on 2026/01/02 08:42:00 UTC

[PR] Feat/sh path extend [apisix]

sihyeonn opened a new pull request, #12857:
URL: https://github.com/apache/apisix/pull/12857

   ### Description
   
   Add `override.path_mode` option to `ai-proxy` and `ai-proxy-multi` plugins to control how the upstream request path is determined.
   
   **Background (Problem)**
   Currently, when `override.endpoint` is set, the URL path is fixed to either the endpoint's path or the driver's default path. This causes issues when:
   - Using a single route for multiple API endpoints (e.g., `/v1/chat/completions` and `/v1/responses`)
   - Wanting to preserve the original request URI path while only overriding the host
   
   **Solution**
   Add `path_mode` option with three modes:
   - `fixed` (default): Existing behavior - uses endpoint path or driver default
   - `preserve`: Uses the original request URI path (with query string)
   - `append`: Appends original request URI path to the endpoint path
   
   This allows using a single route with the same model for multiple API endpoints, reducing route explosion in multi-model deployments.
   
   #### Which issue(s) this PR fixes:
   Fixes #
   
   ### 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
   - [ ] 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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] closed pull request #12857: feat(ai-proxy): add path_mode option to override.endpoint 
URL: https://github.com/apache/apisix/pull/12857


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-4903068127

   This pull request/issue has been closed due to lack of activity. If you think that is incorrect, or the pull request requires review, you can revive the PR at any time.


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "Baoyuantop (via GitHub)" <gi...@apache.org>.
Baoyuantop commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-3798438885

   Hi @sihyeonn, please help resolve the code conflicts.


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "sihyeonn (via GitHub)" <gi...@apache.org>.
sihyeonn commented on code in PR #12857:
URL: https://github.com/apache/apisix/pull/12857#discussion_r2957545892


##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -239,7 +239,36 @@ function _M.request(self, ctx, conf, request_table, extra_opts)
         end
     end
 
-    local path = (parsed_url and parsed_url.path or self.path)
+    local path_mode = extra_opts.path_mode or "fixed"
+    local endpoint_path = parsed_url and parsed_url.path
+    local req_path = ctx.var.uri
+    local path
+
+    if path_mode == "preserve" then
+        path = req_path
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    elseif path_mode == "append" then
+        local prefix = endpoint_path or ""
+        if prefix == "" or prefix == "/" then
+            path = req_path
+        else
+            path = prefix .. req_path
+            path = path:gsub("//+", "/")
+        end
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end

Review Comment:
   Done — extracted the path logic into a build_path() helper.



##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -239,7 +239,36 @@ function _M.request(self, ctx, conf, request_table, extra_opts)
         end
     end
 
-    local path = (parsed_url and parsed_url.path or self.path)
+    local path_mode = extra_opts.path_mode or "fixed"
+    local endpoint_path = parsed_url and parsed_url.path
+    local req_path = ctx.var.uri
+    local path
+
+    if path_mode == "preserve" then
+        path = req_path
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    elseif path_mode == "append" then
+        local prefix = endpoint_path or ""
+        if prefix == "" or prefix == "/" then
+            path = req_path
+        else
+            path = prefix .. req_path
+            path = path:gsub("//+", "/")
+        end
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end

Review Comment:
   Already using ctx.var.is_args in the merge_request_query_params function, kept as is.



##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -239,7 +239,36 @@ function _M.request(self, ctx, conf, request_table, extra_opts)
         end
     end
 
-    local path = (parsed_url and parsed_url.path or self.path)
+    local path_mode = extra_opts.path_mode or "fixed"
+    local endpoint_path = parsed_url and parsed_url.path
+    local req_path = ctx.var.uri
+    local path
+
+    if path_mode == "preserve" then
+        path = req_path
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    elseif path_mode == "append" then
+        local prefix = endpoint_path or ""
+        if prefix == "" or prefix == "/" then
+            path = req_path
+        else
+            path = prefix .. req_path
+            path = path:gsub("//+", "/")
+        end
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    else
+        path = (endpoint_path and endpoint_path ~= "" and endpoint_path) or self.path

Review Comment:
   Handled — build_path falls back to the driver default path when endpoint_path is nil or empty string.



##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -45,8 +45,26 @@ local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR
 local HTTP_GATEWAY_TIMEOUT = ngx.HTTP_GATEWAY_TIMEOUT
 
 
-function _M.new(opt)
-    return setmetatable(opt, mt)
+local function merge_request_query_params(ctx, query_params)
+    if ctx.var.is_args == "?" and ctx.var.args and #ctx.var.args > 0 then
+        local req_args_tab = core.string.decode_args(ctx.var.args)
+        if type(req_args_tab) == "table" then
+            core.table.merge(query_params, req_args_tab)
+        end
+    end
+end
+
+
+function _M.new(opts)
+    local self = {

Review Comment:
   You're right, that was unintentional. Reverted _M.new back to the original setmetatable(opt, mt) so all fields are passed through transparently. Sorry for the delay on this.



##########
apisix/plugins/ai-proxy/schema.lua:
##########
@@ -89,6 +89,15 @@ local ai_instance_schema = {
                         type = "string",
                         description = "To be specified to override the endpoint of the AI Instance",
                     },
+                    path_mode = {

Review Comment:
   path_mode_schema is already defined once and reused across both ai_instance_schema and ai_proxy_schema.



-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "Baoyuantop (via GitHub)" <gi...@apache.org>.
Baoyuantop commented on code in PR #12857:
URL: https://github.com/apache/apisix/pull/12857#discussion_r2752356010


##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -45,8 +45,26 @@ local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR
 local HTTP_GATEWAY_TIMEOUT = ngx.HTTP_GATEWAY_TIMEOUT
 
 
-function _M.new(opt)
-    return setmetatable(opt, mt)
+local function merge_request_query_params(ctx, query_params)
+    if ctx.var.is_args == "?" and ctx.var.args and #ctx.var.args > 0 then
+        local req_args_tab = core.string.decode_args(ctx.var.args)
+        if type(req_args_tab) == "table" then
+            core.table.merge(query_params, req_args_tab)
+        end
+    end
+end
+
+
+function _M.new(opts)
+    local self = {

Review Comment:
   Is this change necessary? It breaks the original transparent pass-through mechanism—now only explicitly listed fields are passed through.



-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "sihyeonn (via GitHub)" <gi...@apache.org>.
sihyeonn commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-3717669609

   @Baoyuantop Thanks for your review. I handled it.


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "Baoyuantop (via GitHub)" <gi...@apache.org>.
Baoyuantop commented on code in PR #12857:
URL: https://github.com/apache/apisix/pull/12857#discussion_r2666863948


##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -239,7 +239,36 @@ function _M.request(self, ctx, conf, request_table, extra_opts)
         end
     end
 
-    local path = (parsed_url and parsed_url.path or self.path)
+    local path_mode = extra_opts.path_mode or "fixed"
+    local endpoint_path = parsed_url and parsed_url.path
+    local req_path = ctx.var.uri
+    local path
+
+    if path_mode == "preserve" then
+        path = req_path
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    elseif path_mode == "append" then
+        local prefix = endpoint_path or ""
+        if prefix == "" or prefix == "/" then
+            path = req_path
+        else
+            path = prefix .. req_path
+            path = path:gsub("//+", "/")
+        end
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    else
+        path = (endpoint_path and endpoint_path ~= "" and endpoint_path) or self.path

Review Comment:
   It needs to be confirmed whether the behavior remains consistent when endpoint_path is an empty string.



##########
apisix/plugins/ai-proxy/schema.lua:
##########
@@ -89,6 +89,15 @@ local ai_instance_schema = {
                         type = "string",
                         description = "To be specified to override the endpoint of the AI Instance",
                     },
+                    path_mode = {

Review Comment:
   It is recommended to extract it as a common schema variable to avoid duplication.



##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -239,7 +239,36 @@ function _M.request(self, ctx, conf, request_table, extra_opts)
         end
     end
 
-    local path = (parsed_url and parsed_url.path or self.path)
+    local path_mode = extra_opts.path_mode or "fixed"
+    local endpoint_path = parsed_url and parsed_url.path
+    local req_path = ctx.var.uri
+    local path
+
+    if path_mode == "preserve" then
+        path = req_path
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    elseif path_mode == "append" then
+        local prefix = endpoint_path or ""
+        if prefix == "" or prefix == "/" then
+            path = req_path
+        else
+            path = prefix .. req_path
+            path = path:gsub("//+", "/")
+        end
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end

Review Comment:
   It can be extracted into a common function.



##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -239,7 +239,36 @@ function _M.request(self, ctx, conf, request_table, extra_opts)
         end
     end
 
-    local path = (parsed_url and parsed_url.path or self.path)
+    local path_mode = extra_opts.path_mode or "fixed"
+    local endpoint_path = parsed_url and parsed_url.path
+    local req_path = ctx.var.uri
+    local path
+
+    if path_mode == "preserve" then
+        path = req_path
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end
+        end
+    elseif path_mode == "append" then
+        local prefix = endpoint_path or ""
+        if prefix == "" or prefix == "/" then
+            path = req_path
+        else
+            path = prefix .. req_path
+            path = path:gsub("//+", "/")
+        end
+        if ctx.var.is_args and ctx.var.args and #ctx.var.args > 0 then
+            local req_args_tab = core.string.decode_args(ctx.var.args)
+            if type(req_args_tab) == "table" then
+                core.table.merge(query_params, req_args_tab)
+            end

Review Comment:
   It is recommended to use `ctx.var.is_args == "?"` to check.



-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "Baoyuantop (via GitHub)" <gi...@apache.org>.
Baoyuantop commented on code in PR #12857:
URL: https://github.com/apache/apisix/pull/12857#discussion_r2917269483


##########
apisix/plugins/ai-drivers/openai-base.lua:
##########
@@ -45,8 +45,26 @@ local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR
 local HTTP_GATEWAY_TIMEOUT = ngx.HTTP_GATEWAY_TIMEOUT
 
 
-function _M.new(opt)
-    return setmetatable(opt, mt)
+local function merge_request_query_params(ctx, query_params)
+    if ctx.var.is_args == "?" and ctx.var.args and #ctx.var.args > 0 then
+        local req_args_tab = core.string.decode_args(ctx.var.args)
+        if type(req_args_tab) == "table" then
+            core.table.merge(query_params, req_args_tab)
+        end
+    end
+end
+
+
+function _M.new(opts)
+    local self = {

Review Comment:
   Hi @sihyeonn, following up on the previous review comments. Please let us know if you have any updates. Thank you.



-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-4648779294

   This pull request has been marked as stale due to 60 days of inactivity. It will be closed in 4 weeks if no further activity occurs. If you think that's incorrect or this pull request should instead be reviewed, please simply write any comment. Even if closed, you can still revive the PR at any time or discuss it on the dev@apisix.apache.org list. Thank you for your contributions.


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "Baoyuantop (via GitHub)" <gi...@apache.org>.
Baoyuantop commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-3707590621

   Hi @sihyeonn, thank you for your contribution. Could you please describe your original requirements in detail? What problems did you encounter while using the current version, and why was this change necessary?


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "sihyeonn (via GitHub)" <gi...@apache.org>.
sihyeonn commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-3708662674

   Hi @Baoyuantop ,
   
   I'm running an LLM gateway. Many models expose multiple endpoints from the same base URL:
   - `/v1/chat/completions`
   - `/v1/responses`
   - `/v1/embeddings`
   - `/v1/moderations`
   
   Currently, I must create separate routes for each endpoint because `override.endpoint` replaces the entire URI:
   ```yaml
   # Example Current: 4 routes per model
   routes:
     - uri: /v1/chat/completions
       plugins:
         ai-proxy:
           override:
             endpoint: https://api.example.com/models/gpt-4/v1/chat/completions
   
     - uri: /v1/responses
       plugins:
         ai-proxy:
           override:
             endpoint: https://api.example.com/models/gpt-4/v1/responses
     # ... 2 more routes
   ```
   
   This creates unnecessary duplication:
   - 4+ routes per model
   - Same base URL repeated across routes
   - Duplicate plugin configs (healthcheck, auth, timeout)
   


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] feat(ai-proxy): add path_mode option to override.endpoint [apisix]

Posted by "sihyeonn (via GitHub)" <gi...@apache.org>.
sihyeonn commented on PR #12857:
URL: https://github.com/apache/apisix/pull/12857#issuecomment-4087397780

   @Baoyuantop Sorry for the delay. Addressed all your feedback — restored transparent pass-through in _M.new, extracted build_path helper, and handled empty endpoint_path. Ready for another look.


-- 
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: notifications-unsubscribe@apisix.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org