openvibers/openvibe.ai Commits

Expose the Exchange icon search on api.openvibe.exchange (#487)

OP OpenVibers committed 2 days ago · 3817a3d375 · 2 files, +16 −1

Changes

ddiff --git a/deploy/nginx/api.openvibe.exchange.conf b/deploy/nginx/api.openvibe.exchange.conf
iindex e594ed4..e8c813e 100644
---- a/deploy/nginx/api.openvibe.exchange.conf
++++ b/deploy/nginx/api.openvibe.exchange.conf
@@@ -69,6 +69,20 @@ server {
proxy_set_header CF-Connecting-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
++ # Exchange search: the icon reference route OpenVibe.Design reaches with its first-party service token
++ # (exchange.search.icons). POST only, the same public API rate limit and upstream as the rest.
++ location = /v1/search/icons {
++ limit_req zone=ovai_apps burst=20 nodelay;
++ limit_req_status 429;
++ limit_except POST { deny all; }
++ proxy_pass http://127.0.0.1:4700;
++ proxy_http_version 1.1;
++ proxy_set_header Host $host;
++ proxy_set_header X-Real-IP $remote_addr;
++ proxy_set_header X-Forwarded-For $remote_addr;
++ proxy_set_header CF-Connecting-IP $remote_addr;
++ proxy_set_header X-Forwarded-Proto $scheme;
++ }
# Exchange's public read API (catalog, a model's offers, aggregate usage) and the OpenAPI document.
location ^~ /api/v1/exchange/ {
limit_req zone=ovai_apps burst=20 nodelay;
@@@ -124,6 +138,6 @@ server {
location / {
default_type application/json;
-- return 404 '{"error":{"message":"Not found. The API is POST /v1/chat/completions, POST /v1/messages and GET /v1/models; docs at https://openvibe.exchange/api","type":"invalid_request_error","code":"not_found"}}';
++ return 404 '{"error":{"message":"Not found. The API is POST /v1/chat/completions, POST /v1/messages, POST /v1/search/icons and GET /v1/models; docs at https://openvibe.exchange/api","type":"invalid_request_error","code":"not_found"}}';
}
}
ddiff --git a/test/exchange-market.test.js b/test/exchange-market.test.js
iindex 3ed6356..0e5d3d3 100644
---- a/test/exchange-market.test.js
++++ b/test/exchange-market.test.js
@@@ -74,6 +74,7 @@ t.test('unregistered pricebook rows survive and the public route is cached and p
assert.strictEqual((await request(h.base,'GET','/api/v1/exchange/market?open_weights=bad')).status,422);
const nginx=fs.readFileSync(path.join(__dirname,'../deploy/nginx/api.openvibe.exchange.conf'),'utf8');
assert(nginx.includes('location ^~ /api/v1/exchange/'));
++ assert(nginx.includes('location = /v1/search/icons'), 'the Exchange icon search reaches OpenVibe.AI from the public API host');
let time=100; let reads=0;
const market=createMarket({db:h.db,registry:{listProviders:async()=>{reads++;return[];},listModels:async()=>[]},catalog:async()=>({models:[]}),clock:{now:()=>time},metadata:{read:async()=>({entries:[],checked_at:null,stale:true})}});
await Promise.all([market.read({limit:1}),market.read({limit:2})]); assert.strictEqual(reads,1);