Skip to content

Commit

Permalink
Merge branch 'master' of github.com:apache/apisix into ai-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
shreemaan-abhishek committed Aug 30, 2024
2 parents e566a37 + 3387916 commit 4c13cef
Show file tree
Hide file tree
Showing 46 changed files with 2,083 additions and 106 deletions.
4 changes: 4 additions & 0 deletions .asf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ github:
dismiss_stale_reviews: true
require_code_owner_reviews: true
required_approving_review_count: 3
release/3.10:
required_pull_request_reviews:
require_code_owner_reviews: true
required_approving_review_count: 3
release/3.9:
required_pull_request_reviews:
require_code_owner_reviews: true
Expand Down
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ title: Changelog

## Table of Contents

- [3.10.0](#3100)
- [3.9.0](#390)
- [3.8.0](#380)
- [3.7.0](#370)
Expand Down Expand Up @@ -76,6 +77,58 @@ title: Changelog
- [0.7.0](#070)
- [0.6.0](#060)

## 3.10.0

### Change

- remove `core.grpc` module [#11427](https://github.com/apache/apisix/pull/11427)
- add max req/resp body size attributes [#11133](https://github.com/apache/apisix/pull/11133)
- autogenerate admin api key if not passed [#11080](https://github.com/apache/apisix/pull/11080)
- enable sensitive fields encryption by default [#11076](https://github.com/apache/apisix/pull/11076)
- support more sensitive fields for encryption [#11095](https://github.com/apache/apisix/pull/11095)

### Plugins

- allow set headers in introspection request [#11090](https://github.com/apache/apisix/pull/11090)

### Bugfixes

- Fix: etcd sync data checker should work [#11457](https://github.com/apache/apisix/pull/11457)
- Fix: plugin metadata add id value for etcd checker [#11452](https://github.com/apache/apisix/pull/11452)
- Fix: allow trailing period in SNI and CN for SSL [#11414](https://github.com/apache/apisix/pull/11414)
- Fix: filter out illegal INT(string) formats [#11367](https://github.com/apache/apisix/pull/11367)
- Fix: make the message clearer when API key is missing [#11370](https://github.com/apache/apisix/pull/11370)
- Fix: report consumer username tag in datadog [#11354](https://github.com/apache/apisix/pull/11354)
- Fix: after updating the header, get the old value from the ctx.var [#11329](https://github.com/apache/apisix/pull/11329)
- Fix: ssl key rotation caused request failure [#11305](https://github.com/apache/apisix/pull/11305)
- Fix: validation fails causing etcd events not to be handled correctly [#11268](https://github.com/apache/apisix/pull/11268)
- Fix: stream route matcher is nil after first match [#11269](https://github.com/apache/apisix/pull/11269)
- Fix: rectify the way to fetch secret resource by id [#11164](https://github.com/apache/apisix/pull/11164)
- Fix: multi-auth raise 500 error when use default conf [#11145](https://github.com/apache/apisix/pull/11145)
- Fix: avoid overwriting `Access-Control-Expose-Headers` response header [#11136](https://github.com/apache/apisix/pull/11136)
- Fix: close session in case of error to avoid blocked session [#11089](https://github.com/apache/apisix/pull/11089)
- Fix: restore `pb.state` appropriately [#11135](https://github.com/apache/apisix/pull/11135)
- Fix: add a default limit of 100 for `get_headers()` [#11140](https://github.com/apache/apisix/pull/11140)
- Fix: disable features when prometheus plugin is turned off [#11117](https://github.com/apache/apisix/pull/11117)
- Fix: add post request headers only if auth request method is POST [#11021](https://github.com/apache/apisix/pull/11021)
- Fix: core.request.header return strings instead of table [#11127](https://github.com/apache/apisix/pull/11127)
- Fix: brotli partial response [#11087](https://github.com/apache/apisix/pull/11087)
- Fix: the port value greater than 65535 should not be allowed [#11043](https://github.com/apache/apisix/pull/11043)

### Core

- upgrade openresty version to 1.25.3.2 [#11419](https://github.com/apache/apisix/pull/11419)
- move config-default.yaml to hardcoded lua file [#11343](https://github.com/apache/apisix/pull/11343)
- warn log when sending requests to external services insecurely [#11403](https://github.com/apache/apisix/pull/11403)
- update casbin to 1.41.9 [#11400](https://github.com/apache/apisix/pull/11400)
- update lua-resty-t1k to 1.1.5 [#11391](https://github.com/apache/apisix/pull/11391)
- support store ssl.keys ssl.certs in secrets mamager [#11339](https://github.com/apache/apisix/pull/11339)
- move tinyyaml to lyaml [#11312](https://github.com/apache/apisix/pull/11312)
- support hcv namespace [#11277](https://github.com/apache/apisix/pull/11277)
- add discovery k8s dump data interface [#11111](https://github.com/apache/apisix/pull/11111)
- make fetch_secrets use cache for performance [#11201](https://github.com/apache/apisix/pull/11201)
- replace 'string.len' with '#' [#11078](https://github.com/apache/apisix/pull/11078)

## 3.9.0

### Change
Expand Down
5 changes: 3 additions & 2 deletions apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ dependencies = {
"nginx-lua-prometheus-api7 = 0.20240201-1",
"jsonschema = 0.9.8",
"lua-resty-ipmatcher = 0.6.1",
"lua-resty-kafka = 0.22-0",
"lua-resty-kafka = 0.23-0",
"lua-resty-logger-socket = 2.0.1-0",
"skywalking-nginx-lua = 0.6.0",
"base64 = 1.5-2",
Expand All @@ -81,7 +81,8 @@ dependencies = {
"lua-resty-ldap = 0.1.0-0",
"lua-resty-t1k = 1.1.5",
"brotli-ffi = 0.3-1",
"lua-ffi-zlib = 0.6-0"
"lua-ffi-zlib = 0.6-0",
"api7-lua-resty-aws == 2.0.1-1",
}

build = {
Expand Down
2 changes: 2 additions & 0 deletions apisix/cli/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ local _M = {
"authz-keycloak",
"proxy-cache",
"body-transformer",
"ai-prompt-template",
"ai-prompt-decorator",
"proxy-mirror",
"proxy-rewrite",
"workflow",
Expand Down
2 changes: 1 addition & 1 deletion apisix/core/version.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
-- @module core.version

return {
VERSION = "3.9.0"
VERSION = "3.10.0"
}
117 changes: 117 additions & 0 deletions apisix/plugins/ai-prompt-decorator.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local core = require("apisix.core")
local ngx = ngx
local pairs = pairs
local EMPTY = {}

local prompt_schema = {
properties = {
role = {
type = "string",
enum = { "system", "user", "assistant" }
},
content = {
type = "string",
minLength = 1,
}
},
required = { "role", "content" }
}

local prompts = {
type = "array",
items = prompt_schema
}

local schema = {
type = "object",
properties = {
prepend = prompts,
append = prompts,
},
anyOf = {
{ required = { "prepend" } },
{ required = { "append" } },
{ required = { "append", "prepend" } },
},
}


local _M = {
version = 0.1,
priority = 1070,
name = "ai-prompt-decorator",
schema = schema,
}


function _M.check_schema(conf)
return core.schema.check(schema, conf)
end


local function get_request_body_table()
local body, err = core.request.get_body()
if not body then
return nil, { message = "could not get body: " .. err }
end

local body_tab, err = core.json.decode(body)
if not body_tab then
return nil, { message = "could not get parse JSON request body: " .. err }
end

return body_tab
end


local function decorate(conf, body_tab)
local new_messages = conf.prepend or EMPTY
for _, message in pairs(body_tab.messages) do
core.table.insert_tail(new_messages, message)
end

for _, message in pairs(conf.append or EMPTY) do
core.table.insert_tail(new_messages, message)
end

body_tab.messages = new_messages
end


function _M.rewrite(conf, ctx)
local body_tab, err = get_request_body_table()
if not body_tab then
return 400, err
end

if not body_tab.messages then
return 400, "messages missing from request body"
end
decorate(conf, body_tab) -- will decorate body_tab in place

local new_jbody, err = core.json.encode(body_tab)
if not new_jbody then
return 500, { message = "failed to parse modified JSON request body: " .. err }
end

ngx.req.set_body_data(new_jbody)
end


return _M
146 changes: 146 additions & 0 deletions apisix/plugins/ai-prompt-template.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local core = require("apisix.core")
local body_transformer = require("apisix.plugins.body-transformer")
local ipairs = ipairs

local prompt_schema = {
properties = {
role = {
type = "string",
enum = { "system", "user", "assistant" }
},
content = {
type = "string",
minLength = 1,
}
},
required = { "role", "content" }
}

local prompts = {
type = "array",
minItems = 1,
items = prompt_schema
}

local schema = {
type = "object",
properties = {
templates = {
type = "array",
minItems = 1,
items = {
type = "object",
properties = {
name = {
type = "string",
minLength = 1,
},
template = {
type = "object",
properties = {
model = {
type = "string",
minLength = 1,
},
messages = prompts
}
}
},
required = {"name", "template"}
}
},
},
required = {"templates"},
}


local _M = {
version = 0.1,
priority = 1071,
name = "ai-prompt-template",
schema = schema,
}

local templates_lrucache = core.lrucache.new({
ttl = 300, count = 256
})

local templates_json_lrucache = core.lrucache.new({
ttl = 300, count = 256
})

function _M.check_schema(conf)
return core.schema.check(schema, conf)
end


local function get_request_body_table()
local body, err = core.request.get_body()
if not body then
return nil, { message = "could not get body: " .. err }
end

local body_tab, err = core.json.decode(body)
if not body_tab then
return nil, { message = "could not get parse JSON request body: ", err }
end

return body_tab
end


local function find_template(conf, template_name)
for _, template in ipairs(conf.templates) do
if template.name == template_name then
return template.template
end
end
return nil
end

function _M.rewrite(conf, ctx)
local body_tab, err = get_request_body_table()
if not body_tab then
return 400, err
end
local template_name = body_tab.template_name
if not template_name then
return 400, { message = "template name is missing in request." }
end

local template = templates_lrucache(template_name, conf, find_template, conf, template_name)
if not template then
return 400, { message = "template: " .. template_name .. " not configured." }
end

local template_json = templates_json_lrucache(template, template, core.json.encode, template)
core.log.info("sending template to body_transformer: ", template_json)
return body_transformer.rewrite(
{
request = {
template = template_json,
input_format = "json"
}
},
ctx
)
end


return _M
Loading

0 comments on commit 4c13cef

Please sign in to comment.