@@ -106,6 +106,66 @@ add_block_preprocessor(sub {
106106 }
107107 }
108108
109+ location /v1/embeddings {
110+ content_by_lua_block {
111+ if ngx.req.get_method() ~= "POST" then
112+ ngx.status = 400
113+ ngx.say("unsupported request method: ", ngx.req.get_method())
114+ end
115+
116+ local header_auth = ngx.req.get_headers()["authorization"]
117+ if header_auth ~= "Bearer token" then
118+ ngx.status = 401
119+ ngx.say("unauthorized")
120+ return
121+ end
122+
123+ ngx.req.read_body()
124+ local body, err = ngx.req.get_body_data()
125+ local json = require("cjson.safe")
126+ body, err = json.decode(body)
127+ if err then
128+ ngx.status = 400
129+ ngx.say("failed to get request body: ", err)
130+ end
131+
132+ if body.model ~= "text-embedding-ada-002" then
133+ ngx.status = 400
134+ ngx.say("unsupported model: ", body.model)
135+ return
136+ end
137+
138+ if body.encoding_format ~= "float" then
139+ ngx.status = 400
140+ ngx.say("unsupported encoding format: ", body.encoding_format)
141+ return
142+ end
143+
144+ ngx.status = 200
145+ ngx.say([[
146+ {
147+ "object": "list",
148+ "data": [
149+ {
150+ "object": "embedding",
151+ "embedding": [
152+ 0.0023064255,
153+ -0.009327292,
154+ -0.0028842222
155+ ],
156+ "index": 0
157+ }
158+ ],
159+ "model": "text-embedding-ada-002",
160+ "usage": {
161+ "prompt_tokens": 8,
162+ "total_tokens": 8
163+ }
164+ }
165+ ]])
166+ }
167+ }
168+
109169 location /random {
110170 content_by_lua_block {
111171 ngx.say("path override works")
@@ -330,19 +390,7 @@ unsupported content-type: application/x-www-form-urlencoded, only application/js
330390
331391
332392
333- === TEST 11: request schema validity check
334- --- request
335- POST /anything
336- { "messages-missing": [ { "role": "system", "content": "xyz" } ] }
337- --- more_headers
338- Authorization: Bearer token
339- --- error_code: 400
340- --- response_body chomp
341- request format doesn't match schema: property "messages" is required
342-
343-
344-
345- === TEST 12: model options being merged to request body
393+ === TEST 11: model options being merged to request body
346394--- config
347395 location /t {
348396 content_by_lua_block {
@@ -405,7 +453,7 @@ options_works
405453
406454
407455
408- === TEST 13 : override path
456+ === TEST 12 : override path
409457--- config
410458 location /t {
411459 content_by_lua_block {
@@ -467,7 +515,7 @@ path override works
467515
468516
469517
470- === TEST 14 : set route with stream = true (SSE)
518+ === TEST 13 : set route with stream = true (SSE)
471519--- config
472520 location /t {
473521 content_by_lua_block {
@@ -510,7 +558,7 @@ passed
510558
511559
512560
513- === TEST 15 : test is SSE works as expected
561+ === TEST 14 : test is SSE works as expected
514562--- config
515563 location /t {
516564 content_by_lua_block {
@@ -568,3 +616,58 @@ passed
568616 }
569617--- response_body_like eval
570618qr/6data: \[DONE\]\n\n/
619+
620+
621+
622+ === TEST 15: proxy embedding endpoint
623+ --- config
624+ location /t {
625+ content_by_lua_block {
626+ local t = require("lib.test_admin").test
627+ local code, body = t('/apisix/admin/routes/1',
628+ ngx.HTTP_PUT,
629+ [[{
630+ "uri": "/embeddings",
631+ "plugins": {
632+ "ai-proxy": {
633+ "provider": "openai",
634+ "auth": {
635+ "header": {
636+ "Authorization": "Bearer token"
637+ }
638+ },
639+ "options": {
640+ "model": "text-embedding-ada-002",
641+ "encoding_format": "float"
642+ },
643+ "override": {
644+ "endpoint": "http://localhost:6724/v1/embeddings"
645+ }
646+ }
647+ }
648+ }]]
649+ )
650+
651+ if code >= 300 then
652+ ngx.status = code
653+ ngx.say(body)
654+ return
655+ end
656+
657+ ngx.say("passed")
658+ }
659+ }
660+ --- response_body
661+ passed
662+
663+
664+
665+ === TEST 16: send request to embedding api
666+ --- request
667+ POST /embeddings
668+ {
669+ "input": "The food was delicious and the waiter..."
670+ }
671+ --- error_code: 200
672+ --- response_body_like eval
673+ qr/.*text-embedding-ada-002*/
0 commit comments