openvibers/openvibe.ai Commits
openvibe-shared v1.5.0 (Track R release manifest), openvibe-contracts v0.32.0
Changes
@@@ -7,7 +7,7 @@"runtime": "node 22, express, better-sqlite3","port": 4700,"domain": "ai.openvibe.network still serves the OpenVibe.Sites placeholder; the service runs on openvibe-ovh (/opt/openvibe.ai, release bdca064, unit openvibe-ai) on 127.0.0.1:4700, loopback only, used by OpenVibe.Live and OpenVibe.Network",-- "contracts": "openvibe-contracts v0.29.0",++ "contracts": "openvibe-contracts v0.32.0","capabilities": ["ai.run.create", "ai.run.read", "ai.workflow.manage", "ai.provider.manage", "ai.usage.read"],"capabilitiesRegistered": true,"providers": ["stub", "openai-compatible", "anthropic", "http-seam", "whisper.cpp"],@@@ -13,8 +13,8 @@"better-sqlite3": "^11.10.0","dotenv": "^16.4.7","express": "^4.21.2",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.29.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"},"engines": {"node": ">=20.0.0"@@@ -1394,9 +1394,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.29.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.29.0",-- "integrity": "sha512-IJhCi0qY7AuvFUt3+QMLkA0vi4WbUecIyQ3rdT7mF0U+pMTDxHZm2XHxpjfF0t7XPhoRCfgnKRZ4M7q7vLlkIA==",++ "version": "0.32.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "integrity": "sha512-ntN58SIG03YDxbhsiIzOM5GRH19jRMHZUYWI3xU2VwovExagF5DdwApLVfezsu84UTJ+V2Jfn+LWDc+Oz8ab+g==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -1410,9 +1410,9 @@}},"node_modules/openvibe-shared": {-- "version": "1.3.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0",-- "integrity": "sha512-w8yl/5+9eend8I2O/DzAJnEAL2N3GTUY7c7pzK+MLJuLAGD8FmJJQ9gwbgyrq70Snjt3ebrg3TlpORhRAp2kgA==",++ "version": "1.5.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0",++ "integrity": "sha512-cehnscuYMkJwuCYGcI6wPSswbUn0bhTyGAaD5feNCoO//2e9gyC7cgjkEcIOtM8DQF3yTuUNyXnOwckIeM4fUg==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0"@@@ -19,8 +19,8 @@"better-sqlite3": "^11.10.0","dotenv": "^16.4.7","express": "^4.21.2",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.29.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"},"optionalDependencies": {"sharp": "^0.33.5"@@@ -36,7 +36,8 @@ function createApp({ config, db, registry, pool, quotas, cache, runs, auth, keys// fail; provider configuration is optional and degrades it (see observability.js).const readiness = createAiReadiness({ db, registry, pool, keys, runs, release: release.release });app.get('/api/ready', readiness.handler);-- app.get('/release.json', release.handler);++ // GET /release.json (ADR-016) and POST /release-metrics (open tabs' update reports into /metrics).++ release.mount(app, { registry: metrics.registry });app.use(runsRouter({ runs, registry, auth, config, log }));app.use(adminRouter({ db, registry, pool, quotas, cache, runs, auth, log }));@@@ -45,6 +45,14 @@ t.test('/api/ready: every check reports; providers is the only optional one', asassert.ok(!r.text.includes('sk-test-not-real'));});++t.test('/release.json: a registry.release-manifest@1 that names where tabs report updates', async () => {++ const r = await request(h.base, 'GET', '/release.json');++ assert.strictEqual(r.status, 200, r.text);++ assert.strictEqual(r.body.service, 'ai');++ assert.deepStrictEqual(require('openvibe-contracts').validate('registry.release-manifest@1', r.body).errors, []);++ assert.strictEqual(r.body.metrics_url, '/release-metrics');++});++t.test('/metrics: 404 through a proxy; queued and running runs, route templates, circuit state direct', async () => {const ids = [];for (let i = 0; i < 3; i++) {
@@ -7,7 +7,7 @@
@@ -7,7 +7,7 @@
"runtime": "node 22, express, better-sqlite3",
"runtime": "node 22, express, better-sqlite3",
"port": 4700,
"port": 4700,
"domain": "ai.openvibe.network still serves the OpenVibe.Sites placeholder; the service runs on openvibe-ovh (/opt/openvibe.ai, release bdca064, unit openvibe-ai) on 127.0.0.1:4700, loopback only, used by OpenVibe.Live and OpenVibe.Network",
"domain": "ai.openvibe.network still serves the OpenVibe.Sites placeholder; the service runs on openvibe-ovh (/opt/openvibe.ai, release bdca064, unit openvibe-ai) on 127.0.0.1:4700, loopback only, used by OpenVibe.Live and OpenVibe.Network",
- "contracts": "openvibe-contracts v0.29.0",
+ "contracts": "openvibe-contracts v0.32.0",
"capabilities": ["ai.run.create", "ai.run.read", "ai.workflow.manage", "ai.provider.manage", "ai.usage.read"],
"capabilities": ["ai.run.create", "ai.run.read", "ai.workflow.manage", "ai.provider.manage", "ai.usage.read"],
"capabilitiesRegistered": true,
"capabilitiesRegistered": true,
"providers": ["stub", "openai-compatible", "anthropic", "http-seam", "whisper.cpp"],
"providers": ["stub", "openai-compatible", "anthropic", "http-seam", "whisper.cpp"],
@@ -13,8 +13,8 @@
@@ -13,8 +13,8 @@
"better-sqlite3": "^11.10.0",
"better-sqlite3": "^11.10.0",
"dotenv": "^16.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express": "^4.21.2",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.29.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"
},
},
"engines": {
"engines": {
"node": ">=20.0.0"
"node": ">=20.0.0"
@@ -1394,9 +1394,9 @@
@@ -1394,9 +1394,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.29.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.29.0",
- "integrity": "sha512-IJhCi0qY7AuvFUt3+QMLkA0vi4WbUecIyQ3rdT7mF0U+pMTDxHZm2XHxpjfF0t7XPhoRCfgnKRZ4M7q7vLlkIA==",
+ "version": "0.32.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "integrity": "sha512-ntN58SIG03YDxbhsiIzOM5GRH19jRMHZUYWI3xU2VwovExagF5DdwApLVfezsu84UTJ+V2Jfn+LWDc+Oz8ab+g==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -1410,9 +1410,9 @@
@@ -1410,9 +1410,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "1.3.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0",
- "integrity": "sha512-w8yl/5+9eend8I2O/DzAJnEAL2N3GTUY7c7pzK+MLJuLAGD8FmJJQ9gwbgyrq70Snjt3ebrg3TlpORhRAp2kgA==",
+ "version": "1.5.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0",
+ "integrity": "sha512-cehnscuYMkJwuCYGcI6wPSswbUn0bhTyGAaD5feNCoO//2e9gyC7cgjkEcIOtM8DQF3yTuUNyXnOwckIeM4fUg==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0"
@@ -19,8 +19,8 @@
@@ -19,8 +19,8 @@
"better-sqlite3": "^11.10.0",
"better-sqlite3": "^11.10.0",
"dotenv": "^16.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express": "^4.21.2",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.29.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"
},
},
"optionalDependencies": {
"optionalDependencies": {
"sharp": "^0.33.5"
"sharp": "^0.33.5"
@@ -36,7 +36,8 @@ function createApp({ config, db, registry, pool, quotas, cache, runs, auth, keys
@@ -36,7 +36,8 @@ function createApp({ config, db, registry, pool, quotas, cache, runs, auth, keys
// fail; provider configuration is optional and degrades it (see observability.js).
// fail; provider configuration is optional and degrades it (see observability.js).
const readiness = createAiReadiness({ db, registry, pool, keys, runs, release: release.release });
const readiness = createAiReadiness({ db, registry, pool, keys, runs, release: release.release });
app.get('/api/ready', readiness.handler);
app.get('/api/ready', readiness.handler);
- app.get('/release.json', release.handler);
+ // GET /release.json (ADR-016) and POST /release-metrics (open tabs' update reports into /metrics).
+ release.mount(app, { registry: metrics.registry });
app.use(runsRouter({ runs, registry, auth, config, log }));
app.use(runsRouter({ runs, registry, auth, config, log }));
app.use(adminRouter({ db, registry, pool, quotas, cache, runs, auth, log }));
app.use(adminRouter({ db, registry, pool, quotas, cache, runs, auth, log }));
@@ -45,6 +45,14 @@ t.test('/api/ready: every check reports; providers is the only optional one', as
@@ -45,6 +45,14 @@ t.test('/api/ready: every check reports; providers is the only optional one', as
assert.ok(!r.text.includes('sk-test-not-real'));
assert.ok(!r.text.includes('sk-test-not-real'));
});
});
+t.test('/release.json: a registry.release-manifest@1 that names where tabs report updates', async () => {
+ const r = await request(h.base, 'GET', '/release.json');
+ assert.strictEqual(r.status, 200, r.text);
+ assert.strictEqual(r.body.service, 'ai');
+ assert.deepStrictEqual(require('openvibe-contracts').validate('registry.release-manifest@1', r.body).errors, []);
+ assert.strictEqual(r.body.metrics_url, '/release-metrics');
+});
+
t.test('/metrics: 404 through a proxy; queued and running runs, route templates, circuit state direct', async () => {
t.test('/metrics: 404 through a proxy; queued and running runs, route templates, circuit state direct', async () => {
const ids = [];
const ids = [];
for (let i = 0; i < 3; i++) {
for (let i = 0; i < 3; i++) {