Skip to content

Commit

Permalink
fix(ai-prompt-guard): fix an issue when allow_all_conversation_history
Browse files Browse the repository at this point in the history
is set to false, the first user request is selected instead of the last
one
  • Loading branch information
fffonion committed Jul 11, 2024
1 parent bc27ffd commit 8e3a665
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 243 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/kong/fix-ai-prompt-guard-order.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
message: "**AI-Prompt-Guard**: Fixed an issue when `allow_all_conversation_history` is set to false, the first user request is selected instead of the last one."
type: bugfix
scope: Plugin
43 changes: 20 additions & 23 deletions kong/plugins/ai-prompt-guard/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ local execute do
-- @tparam table request The deserialized JSON body of the request
-- @tparam table conf The plugin configuration
-- @treturn[1] table The decorated request (same table, content updated)
-- @treturn[2] nil
-- @treturn[2] string The error message
function execute(request, conf)
local user_prompt
local collected_prompts
local messages = request.messages

-- concat all 'user' prompts into one string, if conversation history must be checked
if type(request.messages) == "table" and not conf.allow_all_conversation_history then
-- concat all prompts into one string, if conversation history must be checked
if type(messages) == "table" then
local buf = buffer.new()
-- Note allow_all_conversation_history means ignores history
local just_pick_latest = conf.allow_all_conversation_history

for _, v in ipairs(request.messages) do
-- iterate in reverse so we get the latest user prompt first
-- instead of the oldest one in history
for i=#messages, 1, -1 do
local v = messages[i]
if type(v.role) ~= "string" then
return nil, bad_format_error
end
Expand All @@ -44,41 +49,33 @@ local execute do
return nil, bad_format_error
end
buf:put(v.content)
end
end

user_prompt = buf:get()

elseif type(request.messages) == "table" then
-- just take the trailing 'user' prompt
for _, v in ipairs(request.messages) do
if type(v.role) ~= "string" then
return nil, bad_format_error
end
if v.role == "user" then
if type(v.content) ~= "string" then
return nil, bad_format_error
if just_pick_latest then
break
end
user_prompt = v.content

buf:put(" ") -- put a seperator to avoid adhension of words
end
end

collected_prompts = buf:get()

elseif type(request.prompt) == "string" then
user_prompt = request.prompt
collected_prompts = request.prompt

else
return nil, bad_format_error
end

if not user_prompt then
if not collected_prompts then
return nil, "no 'prompt' or 'messages' received"
end


-- check the prompt for explcit ban patterns
for _, v in ipairs(conf.deny_patterns or EMPTY) do
-- check each denylist; if prompt matches it, deny immediately
local m, _, err = ngx_re_find(user_prompt, v, "jo")
local m, _, err = ngx_re_find(collected_prompts, v, "jo")
if err then
-- regex failed, that's an error by the administrator
kong.log.err("bad regex pattern '", v ,"', failed to execute: ", err)
Expand All @@ -98,7 +95,7 @@ local execute do
-- if any allow_patterns specified, make sure the prompt matches one of them
for _, v in ipairs(conf.allow_patterns or EMPTY) do
-- check each denylist; if prompt matches it, deny immediately
local m, _, err = ngx_re_find(user_prompt, v, "jo")
local m, _, err = ngx_re_find(collected_prompts, v, "jo")

if err then
-- regex failed, that's an error by the administrator
Expand Down
Loading

0 comments on commit 8e3a665

Please sign in to comment.