openvibers/openvibe.exchange Commits

Document Exchange routing and request accounting compatibility (#158)

OP OpenVibers committed 4 days ago · a35a5b42a0 · 2 files, +12 −2

* Document Exchange routing, request presets and accounting

* Clarify the shared Bench rating source used by Report

* State the paid image accounting limitation

Changes

ddiff --git a/server/views/exchange.js b/server/views/exchange.js
iindex 38baf14..3659d9c 100644
---- a/server/views/exchange.js
++++ b/server/views/exchange.js
@@@ -511,6 +511,16 @@ ${kit.snippet({ code: `curl ${ENDPOINT} \\\n -H "Authorization: Bearer $OPENVIB
<p>${kit.button({ href: 'https://openvibe.network/developers', label: 'Make a key on Network' })} ${kit.button({ href: '/privacy/keys', label: 'Your keys and accounts', kind: 'quiet' })}</p>
<h3 class="ex-h3" id="strict">Strict privacy</h3>
${switchBox}
++<h3 class="ex-h3">Routing and fallbacks</h3>
++<p class="ex-prose">Chat completions and Messages accept <code>provider.order</code>, <code>only</code>, <code>ignore</code>, <code>allow_fallbacks</code>, <code>sort</code>, <code>max_price</code>, <code>data_collection</code> and <code>zdr</code>. Put model fallbacks in <code>models: ["maker/first", "maker/backup"]</code>. All attempts share one request hold; an <code>Idempotency-Key</code> replay does not charge again.</p>
++<p class="ex-prose">Sort by <code>price</code>, <code>throughput</code>, <code>latency</code>, <code>quality</code> or <code>value</code>. Quality uses the Bench board rating shown by Report; value is rating per dollar. Offers without the required evidence are excluded. Ratings arrive through the existing Bench event feed; provisional ratings are excluded. Speed uses observed decode throughput or time to first token.</p>
++<p class="ex-prose"><code>max_price: {"prompt": 1, "completion": 2}</code> caps dollars per million tokens. <code>data_collection: "deny"</code> requires no training; <code>zdr: true</code> requires no retention. Unknown facts cannot satisfy a hard limit. Append <code>:free</code>, <code>:floor</code> or <code>:nitro</code> to require zero prices, prefer the lowest price, or prefer measured throughput. Explicit provider credentials and only-my-keys mode cannot currently combine with these routing controls.</p>
++<h3 class="ex-h3">Request accounting</h3>
++<p class="ex-prose"><code>usage: {"include": true}</code> adds cost in dollars, latency in milliseconds and provider to token usage. Look up your own request with <code>GET /v1/generation?id=&lt;response-id&gt;</code>. A different owner receives 404.</p>
++<h3 class="ex-h3">Saved request presets</h3>
++<p class="ex-prose">Save model, fallbacks, system prompt, provider routing and sampling under a name using <code>POST /v1/presets/import</code>, then request <code>@preset/name</code>. Use your person token to list or save at <code>/api/v1/exchange/presets</code>, or delete at <code>/api/v1/exchange/presets/:name</code>. Inference keys do not authorize provisioning. The import preview remains write-free.</p>
++<h3 class="ex-h3">Other compatible endpoints</h3>
++<ul class="ex-prose"><li><code>POST /v1/completions</code>: one string prompt, with streaming.</li><li><code>POST /v1/embeddings</code>: strings or string arrays, float vectors.</li><li><code>GET /v1/models</code>: catalogue entries with per-token pricing, context and provider limits.</li><li><code>POST /v1/images/generations</code>: the existing image adapter on configured non-metered capacity; paid image accounting is not yet supported.</li></ul>
<h3 class="ex-h3">Model ids</h3>
<p class="ex-prose"><code>openvibe/auto</code> lets the router pick by your floor, ceiling and policy, and the answer says which model ran and why. An exact id pins one artifact. Bring your own provider key and those requests pay the provider directly, at no fee from us.</p>
${kit.table({ columns: [{ key: 'model', label: 'Model id', primary: true, html: true }, { key: 'context', label: 'Context', num: true }], rows, label: 'Model ids', stack: false })}
ddiff --git a/server/views/migration.js b/server/views/migration.js
iindex 29a066c..622b4fa 100644
---- a/server/views/migration.js
++++ b/server/views/migration.js
@@@ -8,8 +8,8 @@ function migrationPage(){
section('1. Make your first request',`<p>Set OPENVIBE_KEY to your Exchange key locally. Never put it in browser code. Use a new Idempotency-Key for each logical request; reuse it only when retrying the same input.</p>${kit.snippet({id:'migration-curl',code:curl})}${kit.snippet({id:'migration-sdk',code:sdk})}`)+
section('2. Change your gateway settings',`<div class="xp-models"><table><thead><tr><th>From</th><th>Change</th><th>Check before rollout</th></tr></thead><tbody><tr><td>OpenRouter</td><td>Use https://api.openvibe.exchange/v1 and an Exchange key.</td><td>Use the catalogue's model ids. Provider routing fields need the C2 execution integration; preview results are not an execution policy.</td></tr><tr><td>LiteLLM</td><td>Configure an OpenAI-compatible provider with Exchange's api_base and key.</td><td>Turn off duplicate gateway retry layers; verify timeouts and budget limits in your application.</td></tr><tr><td>Vercel AI SDK</td><td>Configure your OpenAI provider's baseURL and apiKey for Exchange.</td><td>Gateway-specific providerOptions are not automatically translated.</td></tr><tr><td>Portkey</td><td>Point the application's OpenAI client directly to Exchange.</td><td>Portkey configuration ids and virtual-key headers do not carry across; recreate policies explicitly.</td></tr></tbody></table></div>`)+
section('3. Inspect routing without sending a prompt',`<p>Use your Network developer token for the diagnostic routes. They do not hold credits, reveal provider keys or call an upstream. Unknown provider fields are rejected; unknown prices and privacy policies cannot satisfy a hard requirement.</p>${kit.snippet({id:'migration-preview',code:`curl https://api.openvibe.exchange/v1/routing/preview \\\n -H "Authorization: Bearer $OPENVIBE_TOKEN" \\\n -H "Content-Type: application/json" \\\n -d '{"model":"openvibe/auto","provider":{"sort":"price","data_collection":"deny","zdr":true,"max_price":{"prompt":1,"completion":2}}}'`})}<p>The response identifies excluded providers and the rule that excluded them. It is catalogue-only: live availability, account gates and budgets still apply. Quality and speed need measured evidence.</p>`)+
-- section('4. Validate an exported preset',`<p>Send the preset configuration, never an OpenRouter key. This preview validates names, model lists, sampling and provider rules. It returns a validation summary without repeating submitted values and does not save the preset; persistence and execution are pending.</p>${kit.snippet({id:'migration-import',code:`curl https://api.openvibe.exchange/v1/presets/import/preview \\\n -H "Authorization: Bearer $OPENVIBE_TOKEN" \\\n -H "Content-Type: application/json" \\\n -d '{"name":"writer","model":"openvibe/auto","temperature":0.4,"provider":{"sort":"price"}}'`})}`)+
++ section('4. Validate an exported preset',`<p>Send the preset configuration, never an OpenRouter key. This preview validates names, model lists, sampling and provider rules. It returns a validation summary without repeating submitted values and does not save the preset. Save the same definition with POST /v1/presets/import using your person token, then invoke @preset/name.</p>${kit.snippet({id:'migration-import',code:`curl https://api.openvibe.exchange/v1/presets/import/preview \\\n -H "Authorization: Bearer $OPENVIBE_TOKEN" \\\n -H "Content-Type: application/json" \\\n -d '{"name":"writer","model":"openvibe/auto","temperature":0.4,"provider":{"sort":"price"}}'`})}`)+
section('5. Limit the credential',`<p>The key provisioning API accepts a name, monthly_cap_usd, allowed_models and optional expires_at in ISO 8601. Expired keys fail authentication, including reservations made with a previously resolved key. Revocation is immediate. Key metadata never returns the secret again.</p><p>Inspect the completion's x_openvibe receipt for cost and provider. Existing streaming, tool calls and structured outputs use the corresponding provider's capabilities. Test your exact media and caching inputs before moving traffic.</p>`)+
-- section('Compatibility work still under review',`<p>Legacy completions, embeddings and image-generation compatibility endpoints; model suffix execution; model fallbacks and full preset persistence; per-request generation lookup; web grounding; Report quality routing; and task/choice-driven agent streams are not implemented by this guide. The existing API reference documents the currently available endpoints.</p>${kit.button({href:'/api',label:'Current API reference',kind:'quiet'})}`)+`</div>`;
++ section('Compatibility work still under review',`<p>See the API reference for routing execution, model fallbacks, suffixes, saved request presets, generation lookup and compatible endpoints. Image generation needs configured non-metered capacity; paid image accounting remains pending. Quality/value routing uses the Bench ratings shown by Report and refuses offers without established evidence. Web grounding and task/choice-driven agent streams remain separate work.</p>${kit.button({href:'/api',label:'Current API reference',kind:'quiet'})}`)+`</div>`;
}
module.exports={migrationPage};