openvibers/openvibe.services Commits

Services home: the building blocks by plain name, and a way to Vibe for people (#98)

OP OpenVibers committed 20 days ago · 1c9d01394f · 4 files, +34 −3

* The Services home lists the building blocks by their plain names (AI API, Agents, Compute, Storage…) and sends people who only want to use OpenVibe to Vibe

* The home's HTML budget allows the building blocks (46.0 KB in CI)

Changes

ddiff --git a/server/http/home.js b/server/http/home.js
iindex b29ebab..6ad4e28 100644
---- a/server/http/home.js
++++ b/server/http/home.js
@@@ -71,6 +71,32 @@ const BUILD = [
{ title: 'Run jobs on a node', text: 'Send a job to one API; it runs on a node that offers its runtime, including your own computer, and streams its output.', href: 'https://openvibe.run/' },
];
++// The building blocks (plan track K, the owner 2026-10-24: consumer products for people, "while also having our services
++// website" for builders): every service an app can call, by the plain name the network's menus use since contracts
++// 0.213.0, with the domain that documents it. People who only want to use OpenVibe are sent to Vibe.
++const BLOCKS = [
++ { title: 'AI API', text: 'Many models behind one OpenAI-compatible API: chat, summaries, extraction, embeddings, images. Every run says which model answered and what it cost.', href: 'https://ai.openvibe.services/' },
++ { title: 'Agents', text: 'Hand a task in plain words to the best agent for it (OpenVibe\'s own or another platform\'s), checked by a second model, with its cost and why. Runs now or on a schedule.', href: 'https://openvibe.actor/docs' },
++ { title: 'Compute', text: 'Send a job to one API; it runs on a node that offers its runtime, your own computer included, metered per second.', href: 'https://openvibe.run/' },
++ { title: 'Storage', text: 'Private S3-compatible zones per project and environment, for the AWS SDKs, rclone and backup tools.', href: 'https://openvibe.zone/' },
++ { title: 'Media API', text: 'Upload, transcode and serve video, clips and files from your project\'s own space, with signed links.', href: 'https://openvibe.media/' },
++ { title: 'Events', text: 'Publish to your project\'s topic and follow it with durable cursors or signed webhooks.', href: 'https://openvibe.events/' },
++ { title: 'Search', text: 'Streams, recordings, posts, jobs, rentals and help answers across the network in one query.', href: '/docs/api/search' },
++ { title: 'Robots and devices', text: 'Pair a robot or a computer, drive it through one gate with roles, limits and an e-stop, and write drivers as plugins.', href: 'https://openvibe.bot/' },
++ { title: 'Sign-in and accounts', text: 'OAuth 2.0 with PKCE for your users, scoped capability grants for your apps, export and deletion handled for you.', href: '/docs' },
++ { title: 'Payments and items', text: 'Tips, memberships and checkout through one ledger; items people earn and wear across every site.', href: 'https://openvibe.vip/' },
++ { title: 'Game services', text: 'Achievements, leaderboards and cloud saves for any game.', href: 'https://play.openvibe.network/' },
++ { title: 'Code with any agent', text: 'The open coding-agent harness: Claude Code, Codex, OpenCode, DeepSeek and self-hosted models behind one router.', href: 'https://openvibe.codes/' },
++];
++
++function blocks() {
++ return showcase.features({
++ id: 'blocks', title: 'The building blocks',
++ lede: 'Every OpenVibe product runs on these, and your app can call the same ones with a project\'s token.',
++ items: BLOCKS,
++ }).replace(/<\/section>$/, () => '<p class="sc-note">Just want to use OpenVibe? <a href="https://openvibe.chat/vibe">Chat with Vibe</a>, OpenVibe\'s assistant, or <a href="https://openvibe.network/">see everything people do here</a>.</p></section>');
++}
++
function build() {
return showcase.features({
id: 'build', title: 'What you can build today',
@@@ -143,4 +169,4 @@ function limitAmount(v, unit) {
}
}
--module.exports = { createNetworkStatus, numbers, build, quickStart, faq, FAQ, BUILD, limitAmount, publicCaps };
++module.exports = { createNetworkStatus, numbers, blocks, build, quickStart, faq, FAQ, BLOCKS, BUILD, limitAmount, publicCaps };
ddiff --git a/server/http/pages.js b/server/http/pages.js
iindex 3cf0cb4..b5b6c7b 100644
---- a/server/http/pages.js
++++ b/server/http/pages.js
@@@ -82,6 +82,7 @@ const services = await registry.services();`;
}))}
<div class="notice">Status: alpha. What works and what does not is listed on the <a href="/policy/transparency">transparency page</a>.</div>
${raw(home.numbers({ docs, programmable, status: (ctx.networkStatus || networkStatus).peek() }))}
++${raw(home.blocks())}
${raw(home.build())}
${raw(home.quickStart({ sdkVersion: docs.sdkVersion }))}
${raw(showcase.features({
ddiff --git a/test/home.test.js b/test/home.test.js
iindex fbec267..ac8ffa2 100644
---- a/test/home.test.js
++++ b/test/home.test.js
@@@ -56,7 +56,7 @@ const { boot, check, done } = require('./helpers/boot');
const t = await boot();
try {
-- await check('the home page: hero code that runs, numbers, what you can build, quick start, FAQ and its JSON-LD', async () => {
++ await check('the home page: hero code that runs, numbers, the building blocks, what you can build, quick start, FAQ and its JSON-LD', async () => {
let r = await t.get('/');
assert.strictEqual(r.status, 200);
assert.ok(!/ov\.registry\./.test(r.text), 'the hero code no longer calls a client property the SDK does not have');
@@@ -68,6 +68,10 @@ const { boot, check, done } = require('./helpers/boot');
assert.ok(r.text.includes(`href="https://github.com/OpenVibers/OpenVibe.Examples/tree/main/examples/${name}"`), `links the ${name} example`);
}
assert.match(r.text, /id="quick-start"/);
++ // The building blocks by their plain names, each linked; people who only want to use OpenVibe go to Vibe.
++ assert.match(r.text, /id="blocks"/);
++ for (const b of home.BLOCKS) assert.ok(r.text.includes(b.title.replace(/'/g, '&#39;')) && r.text.includes(`href="${b.href}"`), `the ${b.title} block`);
++ assert.ok(r.text.includes('<a href="https://openvibe.chat/vibe">Chat with Vibe</a>'), 'people are sent to Vibe');
assert.match(r.text, /\d+ capabilit(y|ies)( · \d+ event types?)?<\/small>/, 'each service says what an app can be granted');
assert.ok(!/per_minute|\d bytes</.test(r.text), 'limits read in plain units');
const blocks = [...r.text.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map((m) => JSON.parse(m[1]));
ddiff --git a/test/perf-budget.test.js b/test/perf-budget.test.js
iindex bad4f1d..15220b8 100644
---- a/test/perf-budget.test.js
++++ b/test/perf-budget.test.js
@@@ -12,7 +12,7 @@ const { spawn } = require('child_process');
const { measure, check, format } = require('openvibe-shared/perf-budget');
const BUDGETS = {
-- htmlRawKB: 45, // 42.9 with the home's own sections (2026-10-22: the platform in numbers, nine text-only "what you can build" cards, three quick-start samples, six FAQs and their FAQPage JSON-LD); 33.7 with openvibe-contracts 0.209 (2026-10-20: Blog, Reviews, Wiki, Coupons, Deals, Trade, Space, Host and News opened capabilities to apps, so the text-only catalog of services you can build on lists them); 30.8 on 2026-10-08 (six ring icons plus that catalog)
++ htmlRawKB: 48, // 46.0 with the twelve text-only building blocks (plan track K, 2026-10-24); 42.9 with the home's own sections (2026-10-22: the platform in numbers, nine text-only "what you can build" cards, three quick-start samples, six FAQs and their FAQPage JSON-LD); 33.7 with openvibe-contracts 0.209 (2026-10-20: Blog, Reviews, Wiki, Coupons, Deals, Trade, Space, Host and News opened capabilities to apps, so the text-only catalog of services you can build on lists them); 30.8 on 2026-10-08 (six ring icons plus that catalog)
htmlBrotliKB: 11, // 10.0 with those sections (2026-10-22); 7.4
jsFiles: 5, // 5 (theme-loader, web-runtime, navbar, footer, boost: openvibe-shared/shell adds web-runtime, 2026-10-04)
jsRawKB: 256, // 254.1 with openvibe-shared 4.9.0 (status text twins in every theme, 2026-10-23); 246.2 with openvibe-shared 4.2.x (Ask Actor in the navbar, 2026-10-15); 239.1 (212.2 before openvibe-shared/shell's web-runtime.js)