openvibers/openvibe.ai Commits

/stats (price and latency) is in search: index,follow with a description and canonical (the console layout made it noindex while the sitemap listed it) (#131)

OP OpenVibers committed 24 days ago · 2d5197fdb8 · 3 files, +18 −5

Changes

ddiff --git a/server/app.js b/server/app.js
iindex b0d1b0d..afb21d8 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -116,7 +116,7 @@ function createApp({ config, db, registry, pool, quotas, cache, runs, auth, keys
res.setHeader('Cache-Control', cachePolicy.htmlHeaders());
res.setHeader('Content-Security-Policy', views.CSP);
res.type('html').send(views.pages.stats({
-- days: STATS_DAYS, rows,
++ days: STATS_DAYS, rows, canonical: `${String(config.baseUrl || '').replace(/\/+$/, '')}/stats`,
from: new Date(now - STATS_DAYS * 86400000).toISOString().slice(0, 10), to: new Date(now).toISOString().slice(0, 10),
}));
} catch (e) { next(e); }
ddiff --git a/server/console/views.js b/server/console/views.js
iindex fdbfb74..e673436 100644
---- a/server/console/views.js
++++ b/server/console/views.js
@@@ -119,9 +119,11 @@ const NAV = [
['/console/quotas', 'Quotas', 'quotas'], ['/console/usage', 'Usage', 'usage'], ['/console/cache', 'Cache', 'cache'], ['/console/audit', 'Audit', 'audit'],
];
--function layout({ title, section, staff, csrf, notice, error, body, site = 'operator console' }) {
++// The console's pages are noindex; the one public page drawn with this layout (/stats) passes robots, a description and
++// its canonical.
++function layout({ title, section, staff, csrf, notice, error, body, site = 'operator console', robots = 'noindex,nofollow', description = null, canonical = null }) {
return `<!doctype html>${render(html`<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
--<meta name="robots" content="noindex,nofollow"><meta name="referrer" content="no-referrer"><title>${title} · AI ${site}</title><style>${new Raw(CSS)}</style></head>
++<meta name="robots" content="${robots}">${description ? html`<meta name="description" content="${description}">` : ''}${canonical ? html`<link rel="canonical" href="${canonical}">` : ''}<meta name="referrer" content="no-referrer"><title>${title} · AI ${site}</title><style>${new Raw(CSS)}</style></head>
<body><a class="skip" href="#main">Skip to content</a><header><div class="bar"><span class="brand">OpenVibe.AI · ${site}</span>
${staff ? html`<nav aria-label="Console"><ul>${NAV.map(([href, label, id]) => html`<li><a href="${href}"${id === section ? html` aria-current="page"` : ''}>${label}</a></li>`)}</ul></nav>
<div class="who"><span>${staff.username ? `@${staff.username} ` : ''}<code>${staff.subject}</code> · ${staff.role}</span>
@@@ -512,9 +514,12 @@ function allowance(cards) {
* Public price and latency per provider and model: provider_stats_daily totals (quotas.statsFor) and the
* rate cards only. Nothing here is per caller; rows: { provider, model, capability, requests, ok, p50, p95, cards }.
*/
--function stats({ days, from, to, rows }) {
++function stats({ days, from, to, rows, canonical = null }) {
return layout({
-- title: 'Price and latency', site: 'stats', body: html`<h1>Price and latency</h1>
++ // In search, as the sitemap and robots.txt say: it was noindex,nofollow from the console's layout.
++ title: 'Price and latency', site: 'stats', robots: 'index,follow', canonical,
++ description: `Price and latency of every AI model OpenVibe.AI called in the last ${days} days: p50 and p95 latency, success rate, price per million tokens and the free allowance.`,
++ body: html`<h1>Price and latency</h1>
<p class="muted">Every provider and model AI called in the last ${days} UTC days (${from} to ${to}). Latency is the upper bound of a fixed latency bucket, the slowest day in the window; prices are per million tokens from the current rate cards.</p>
${table(`Providers and models, ${from} to ${to}`, ['Provider', 'Model', 'Capability', 'p50', 'p95', 'Success rate', 'Price', 'Free allowance'], rows.map((r) => html`<tr>
<td><code>${r.provider}</code></td><td>${r.model ? html`<code>${r.model}</code>` : '—'}</td><td>${r.capability || '—'}</td>
ddiff --git a/test/home.test.js b/test/home.test.js
iindex 00326cc..d7a6c71 100644
---- a/test/home.test.js
++++ b/test/home.test.js
@@@ -78,6 +78,14 @@ t.test('/updates: what shipped on this site, the shared update log, with one hea
assert.ok(r.headers.get('content-security-policy').includes("connect-src 'self' https://openvibe.network"), 'the log reads the network changelog');
});
++t.test('/stats (price and latency) is in search: index,follow, its own description and canonical', async () => {
++ const r = await request(h.base, 'GET', '/stats');
++ assert.strictEqual(r.status, 200);
++ assert.ok(r.text.includes('<meta name="robots" content="index,follow">'), 'indexable');
++ assert.match(r.text, /<meta name="description" content="Price and latency of every AI model OpenVibe\.AI called in the last 7 days: [^"]+">/);
++ assert.ok(r.text.includes(`<link rel="canonical" href="${SITE}/stats">`), 'canonical');
++});
++
t.test('robots.txt, sitemap.xml and llms.txt name the public origin', async () => {
const robots = await request(h.base, 'GET', '/robots.txt');
assert.strictEqual(robots.status, 200);