openvibers/openvibe.ai Commits
Refresh AI service manifest and bump openvibe-contracts to v0.86.0 (#12)
Changes
@@@ -1,5 +1,6 @@# ═══════════════════════════════════════════════════════════════# ai.openvibe.network — OpenVibe.AI Environment Configuration++# Target host: ai.openvibe.services (the public home; BASE_URL still defaults to ai.openvibe.network here).# Copy to .env and fill in values. In production this lives at /etc/openvibe/ai.env (0600).# Secrets are read by NAME only (providers store 'env:NAME' references); nothing logs or returns them.# ═══════════════════════════════════════════════════════════════@@@ -32,6 +33,7 @@ OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000# ── Operator console (/console; README "Operator console") ──# Network SSO as OAuth client `ai` (the client AI's service tokens use). The Network must list# ${BASE_URL}/auth/callback (https://ai.openvibe.network/auth/callback) as a redirect URI of client `ai`.++# Target host: also list https://ai.openvibe.services/auth/callback when BASE_URL moves there.# OV_OAUTH_CLIENT_SECRET is also what the events relay and the user modules authenticate with.#OV_OAUTH_CLIENT_ID=ai#OV_OAUTH_CLIENT_SECRET=@@@ -6,7 +6,7 @@(loopback only) and in production use: OpenVibe.Live runs with `AI_SERVICE=remote` and Network'sfooter copy runs `network.site_copy` here. It is not a public product: the domain keeps its placeholderpage until the launch rule below is met.--**Domain:** `ai.openvibe.network` · **Port:** 4700 · **Unit:** `openvibe-ai.service`++**Domain:** `ai.openvibe.network` (target host `ai.openvibe.services`) · **Port:** 4700 · **Unit:** `openvibe-ai.service`**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §12.1, §12.13, §15.14, §33, §34.**License:** AGPL-3.0 (same as every OpenVibe service).@@@ -43,7 +43,7 @@ owns publication truth: Wiki, Blog, News, Live, … decide what to publish.- OpenVibe.Media (recordings `media.analyze` reads, over allow-listed https URLs or signed URLs)- provider APIs configured by the operator (OpenAI-compatible, Anthropic, the HTTP seam), whisper.cppand the local model server `openvibe-llm.service` on this host--- `openvibe-contracts` v0.84.0, `openvibe-sdk` v0.26.0 (service tokens, events outbox),++- `openvibe-contracts` v0.86.0, `openvibe-sdk` v0.26.0 (service tokens, events outbox),`openvibe-shared` v2.3.1, pinned by release tarball## Capabilities@@@ -7,7 +7,7 @@"runtime": "node 22, express, postgresql","port": 4700,"domain": "ai.openvibe.network still serves the OpenVibe.Sites placeholder; the service runs on openvibe-ovh (/opt/openvibe.ai, unit openvibe-ai) on 127.0.0.1:4700, loopback only, used by OpenVibe.Live and OpenVibe.Network",-- "contracts": "openvibe-contracts v0.84.0",++ "contracts": "openvibe-contracts v0.86.0","sdk": "openvibe-sdk v0.26.0","capabilities": ["ai.run.create",nnew file mode 100644@@@ -0,0 +1,23 @@++{++ "id": "ai.credential.manage",++ "version": "1.0",++ "owner": "ai",++ "status": "active",++ "visibility": "first-party",++ "description": "Store, read (never the key) or delete a person's own provider key, for runs made on their behalf with it (ai.run-request credential). Only the service that stored a credential reads, uses or changes it.",++ "permissions": [++ "ai:credentials"++ ],++ "resourceConstraints": [++ "owner"++ ],++ "quotaClass": "ai-credentials",++ "events": [],++ "implementedBy": [++ "PUT /api/v1/credentials/:subject",++ "GET /api/v1/credentials/:subject",++ "DELETE /api/v1/credentials/:subject"++ ],++ "inputSchema": "ai.credential-put@1",++ "outputSchema": "ai.credential@1"++}nnew file mode 100644@@@ -0,0 +1,23 @@++{++ "id": "ai.quota.attribution.manage",++ "version": "1.0",++ "owner": "ai",++ "status": "active",++ "visibility": "first-party",++ "description": "Cap what runs attributed to one of the caller's own entities may cost or request per hour or day (a streamer's daily AI budget on Live). Only the service named in the attribution sets, reads or removes its caps; a run over a cap is refused before any provider is called.",++ "permissions": [++ "ai:quotas"++ ],++ "resourceConstraints": [++ "owner"++ ],++ "quotaClass": "ai-quotas",++ "events": [],++ "implementedBy": [++ "PUT /api/v1/attribution-quotas/:attribution",++ "GET /api/v1/attribution-quotas/:attribution",++ "DELETE /api/v1/attribution-quotas/:attribution"++ ],++ "inputSchema": "ai.attribution-quota-put@1",++ "outputSchema": "ai.attribution-quota@1"++}@@@ -1,5 +1,5 @@{-- "version": "0.1.0",++ "version": "0.2.0","contractRanges": {"openvibe-contracts": ">=0.6.0 <1.0.0"},@@@ -13,15 +13,77 @@"publicOrigin": "https://ai.openvibe.network","health": "/api/health","ready": "/api/ready",++ "internalOrigin": "http://127.0.0.1:4700",++ "exposure": {++ "state": "internal",++ "publicSite": null,++ "note": "called by other services at 127.0.0.1:4700; ai.openvibe.network serves the OpenVibe.Sites placeholder page"++ },"capabilities": [++ "ai.credential.manage",++ "ai.provider.manage",++ "ai.quota.attribution.manage","ai.run.create","ai.run.read",-- "ai.workflow.manage",-- "ai.provider.manage",-- "ai.usage.read"++ "ai.usage.read",++ "ai.workflow.manage"++ ],++ "eventsProduced": [++ "ai.run.queued",++ "ai.run.succeeded",++ "ai.run.failed",++ "ai.run.cached"],-- "eventsProduced": [],"eventsConsumed": [],-- "namespacesOwned": [],-- "notes": "Providers, models, routing profiles, versioned prompt templates and workflows, runs, request logs, citations, scoped cache, quotas and audit. Workflow output is a draft/evidence package attributed to workflow + model + run. ai.run.queued|succeeded|failed|cached events follow once the Events client is wired in."++ "namespacesOwned": [++ "ai.usage_summary"++ ],++ "lifecycle": {++ "liveness": {++ "endpoint": "/api/health",++ "means": "the process is up and answers HTTP; it checks nothing else (the database and dependencies are what ready checks)"++ },++ "shutdown": {++ "signal": "SIGTERM",++ "deadlineSeconds": 10,++ "drains": [++ "housekeeping timer, user-module sync and Network key refresh stopped",++ "open HTTP connections closed (closeAllConnections), then the server",++ "runs in progress awaited (runs.drain)",++ "ai.run.* outbox relay stopped after the runs (its send in progress awaited; unsent rows stay for the next start)",++ "whisper child processes killed",++ "database closed"++ ],++ "note": "the forced exit after 10 s exits 1"++ },++ "startupRecovery": {++ "resumes": [++ {++ "kind": "jobs",++ "what": "runs left queued or running are marked failed with error_code run.interrupted (announced as ai.run.failed); the caller retries them"++ },++ {++ "kind": "outbox",++ "what": "unsent ai.run.* events in the outbox (server/events.js) go to OpenVibe.Events once the relay starts"++ }++ ]++ },++ "rollback": {++ "conditions": [++ "automatic: ovhost deploy puts the previous sha back and restarts again when the ready URL does not answer 2xx within ready.timeoutSeconds after the restart (exit 3)",++ "manual: ovhost rollback <service> --to <sha>"++ ],++ "window": "automatic only while ovhost waits for readiness after the restart (30 s in host.example.json); manual afterwards, as long as no blocker applies",++ "blockers": {++ "none": "the schema code only adds (CREATE … IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"++ }++ },++ "contracts": {++ "range": ">=0.6.0 <1.0.0"++ },++ "leases": {++ "none": "no claims: one process owns ai.db (better-sqlite3, single writer); a run is taken with a compare-and-set on its status (queued → running)"++ }++ },++ "notes": "Providers, models, routing profiles, versioned prompt templates and workflows, runs, request logs, citations, scoped cache, quotas and audit. Workflow output is a draft/evidence package attributed to workflow + model + run. ai.run.queued|succeeded|failed|cached have payload contracts (v0.30.0, status planned): AI publishes them once its Events client is wired in; it publishes none today. ai.run.create takes ai.run-request@1 and returns ai.run@1."}@@@ -12,7 +12,7 @@"ajv": "^8.17.1","dotenv": "^16.4.7","express": "^4.21.2",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.84.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.86.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0","pg": "^8.23.0"@@@ -1448,9 +1448,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.84.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.84.0",-- "integrity": "sha512-wnmQbzffd2xXSGk3Zr1JxZYIL4oSlnJTo8lGpUApBPoDKeQ3U4VCLJgt3cZpbtkbl5NH1qNjBDXkwx+uASwoyA==",++ "version": "0.86.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.86.0",++ "integrity": "sha512-3o3AILEBtQ2pK0KqK7GEAlN3HJjaKUl6vrbzEDiBbhK6Nr2hivgN/5MAmJ7WRkgaDkxNsZETs/fLZC2Q4oNCiA==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -24,7 +24,7 @@"ajv": "^8.17.1","dotenv": "^16.4.7","express": "^4.21.2",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.84.0",++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.86.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0","openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0","pg": "^8.23.0"@@@ -8,9 +8,10 @@* PEM, which skips the fetch entirely.** Capabilities ai.run.create / ai.run.read / ai.workflow.manage / ai.provider.manage / ai.usage.read-- * are proposed in docs/capabilities-proposal/ and are not in openvibe-contracts yet. Until they-- * ship, allows() decides with the contracts' own grant rule (the exact id, or a `family.*` grant);-- * once contracts knows an id, contracts decides.++ * are proposed in docs/capabilities-proposal/ and are not in openvibe-contracts yet; ai.credential.manage++ * and ai.quota.attribution.manage ship in contracts (0.73.0 / 0.75.0). Until the five do, allows()++ * decides with the contracts' own grant rule (the exact id, or a `family.*` grant); once contracts++ * knows an id, contracts decides.** Namespaces fail closed: a token may only run workflows inside the namespaces its `ns` claim holds* (the same matching as contracts' namespaceAllowed: 'live.*' allows 'live.translate'). A token@@@ -27,6 +28,8 @@ const CAPS = Object.freeze({workflowManage: 'ai.workflow.manage',providerManage: 'ai.provider.manage',usageRead: 'ai.usage.read',++ credentialManage: 'ai.credential.manage',++ quotaAttributionManage: 'ai.quota.attribution.manage',});/**
@@ -1,5 +1,6 @@
@@ -1,5 +1,6 @@
# ═══════════════════════════════════════════════════════════════
# ═══════════════════════════════════════════════════════════════
# ai.openvibe.network — OpenVibe.AI Environment Configuration
# ai.openvibe.network — OpenVibe.AI Environment Configuration
+# Target host: ai.openvibe.services (the public home; BASE_URL still defaults to ai.openvibe.network here).
# Copy to .env and fill in values. In production this lives at /etc/openvibe/ai.env (0600).
# Copy to .env and fill in values. In production this lives at /etc/openvibe/ai.env (0600).
# Secrets are read by NAME only (providers store 'env:NAME' references); nothing logs or returns them.
# Secrets are read by NAME only (providers store 'env:NAME' references); nothing logs or returns them.
# ═══════════════════════════════════════════════════════════════
# ═══════════════════════════════════════════════════════════════
@@ -32,6 +33,7 @@ OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000
@@ -32,6 +33,7 @@ OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000
# ── Operator console (/console; README "Operator console") ──
# ── Operator console (/console; README "Operator console") ──
# Network SSO as OAuth client `ai` (the client AI's service tokens use). The Network must list
# Network SSO as OAuth client `ai` (the client AI's service tokens use). The Network must list
# ${BASE_URL}/auth/callback (https://ai.openvibe.network/auth/callback) as a redirect URI of client `ai`.
# ${BASE_URL}/auth/callback (https://ai.openvibe.network/auth/callback) as a redirect URI of client `ai`.
+# Target host: also list https://ai.openvibe.services/auth/callback when BASE_URL moves there.
# OV_OAUTH_CLIENT_SECRET is also what the events relay and the user modules authenticate with.
# OV_OAUTH_CLIENT_SECRET is also what the events relay and the user modules authenticate with.
#OV_OAUTH_CLIENT_ID=ai
#OV_OAUTH_CLIENT_ID=ai
#OV_OAUTH_CLIENT_SECRET=
#OV_OAUTH_CLIENT_SECRET=
@@ -6,7 +6,7 @@
@@ -6,7 +6,7 @@
(loopback only) and in production use: OpenVibe.Live runs with `AI_SERVICE=remote` and Network's
(loopback only) and in production use: OpenVibe.Live runs with `AI_SERVICE=remote` and Network's
footer copy runs `network.site_copy` here. It is not a public product: the domain keeps its placeholder
footer copy runs `network.site_copy` here. It is not a public product: the domain keeps its placeholder
page until the launch rule below is met.
page until the launch rule below is met.
-**Domain:** `ai.openvibe.network` · **Port:** 4700 · **Unit:** `openvibe-ai.service`
+**Domain:** `ai.openvibe.network` (target host `ai.openvibe.services`) · **Port:** 4700 · **Unit:** `openvibe-ai.service`
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §12.1, §12.13, §15.14, §33, §34.
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §12.1, §12.13, §15.14, §33, §34.
**License:** AGPL-3.0 (same as every OpenVibe service).
**License:** AGPL-3.0 (same as every OpenVibe service).
@@ -43,7 +43,7 @@ owns publication truth: Wiki, Blog, News, Live, … decide what to publish.
@@ -43,7 +43,7 @@ owns publication truth: Wiki, Blog, News, Live, … decide what to publish.
- OpenVibe.Media (recordings `media.analyze` reads, over allow-listed https URLs or signed URLs)
- OpenVibe.Media (recordings `media.analyze` reads, over allow-listed https URLs or signed URLs)
- provider APIs configured by the operator (OpenAI-compatible, Anthropic, the HTTP seam), whisper.cpp
- provider APIs configured by the operator (OpenAI-compatible, Anthropic, the HTTP seam), whisper.cpp
and the local model server `openvibe-llm.service` on this host
and the local model server `openvibe-llm.service` on this host
-- `openvibe-contracts` v0.84.0, `openvibe-sdk` v0.26.0 (service tokens, events outbox),
+- `openvibe-contracts` v0.86.0, `openvibe-sdk` v0.26.0 (service tokens, events outbox),
`openvibe-shared` v2.3.1, pinned by release tarball
`openvibe-shared` v2.3.1, pinned by release tarball
## Capabilities
## Capabilities
@@ -7,7 +7,7 @@
@@ -7,7 +7,7 @@
"runtime": "node 22, express, postgresql",
"runtime": "node 22, express, postgresql",
"port": 4700,
"port": 4700,
"domain": "ai.openvibe.network still serves the OpenVibe.Sites placeholder; the service runs on openvibe-ovh (/opt/openvibe.ai, 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, unit openvibe-ai) on 127.0.0.1:4700, loopback only, used by OpenVibe.Live and OpenVibe.Network",
- "contracts": "openvibe-contracts v0.84.0",
+ "contracts": "openvibe-contracts v0.86.0",
"sdk": "openvibe-sdk v0.26.0",
"sdk": "openvibe-sdk v0.26.0",
"capabilities": [
"capabilities": [
"ai.run.create",
"ai.run.create",
new file mode 100644
new file mode 100644
@@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
+{
+ "id": "ai.credential.manage",
+ "version": "1.0",
+ "owner": "ai",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Store, read (never the key) or delete a person's own provider key, for runs made on their behalf with it (ai.run-request credential). Only the service that stored a credential reads, uses or changes it.",
+ "permissions": [
+ "ai:credentials"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
+ "quotaClass": "ai-credentials",
+ "events": [],
+ "implementedBy": [
+ "PUT /api/v1/credentials/:subject",
+ "GET /api/v1/credentials/:subject",
+ "DELETE /api/v1/credentials/:subject"
+ ],
+ "inputSchema": "ai.credential-put@1",
+ "outputSchema": "ai.credential@1"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
+{
+ "id": "ai.quota.attribution.manage",
+ "version": "1.0",
+ "owner": "ai",
+ "status": "active",
+ "visibility": "first-party",
+ "description": "Cap what runs attributed to one of the caller's own entities may cost or request per hour or day (a streamer's daily AI budget on Live). Only the service named in the attribution sets, reads or removes its caps; a run over a cap is refused before any provider is called.",
+ "permissions": [
+ "ai:quotas"
+ ],
+ "resourceConstraints": [
+ "owner"
+ ],
+ "quotaClass": "ai-quotas",
+ "events": [],
+ "implementedBy": [
+ "PUT /api/v1/attribution-quotas/:attribution",
+ "GET /api/v1/attribution-quotas/:attribution",
+ "DELETE /api/v1/attribution-quotas/:attribution"
+ ],
+ "inputSchema": "ai.attribution-quota-put@1",
+ "outputSchema": "ai.attribution-quota@1"
+}
@@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
{
{
- "version": "0.1.0",
+ "version": "0.2.0",
"contractRanges": {
"contractRanges": {
"openvibe-contracts": ">=0.6.0 <1.0.0"
"openvibe-contracts": ">=0.6.0 <1.0.0"
},
},
@@ -13,15 +13,77 @@
@@ -13,15 +13,77 @@
"publicOrigin": "https://ai.openvibe.network",
"publicOrigin": "https://ai.openvibe.network",
"health": "/api/health",
"health": "/api/health",
"ready": "/api/ready",
"ready": "/api/ready",
+ "internalOrigin": "http://127.0.0.1:4700",
+ "exposure": {
+ "state": "internal",
+ "publicSite": null,
+ "note": "called by other services at 127.0.0.1:4700; ai.openvibe.network serves the OpenVibe.Sites placeholder page"
+ },
"capabilities": [
"capabilities": [
+ "ai.credential.manage",
+ "ai.provider.manage",
+ "ai.quota.attribution.manage",
"ai.run.create",
"ai.run.create",
"ai.run.read",
"ai.run.read",
- "ai.workflow.manage",
- "ai.provider.manage",
- "ai.usage.read"
+ "ai.usage.read",
+ "ai.workflow.manage"
+ ],
+ "eventsProduced": [
+ "ai.run.queued",
+ "ai.run.succeeded",
+ "ai.run.failed",
+ "ai.run.cached"
],
],
- "eventsProduced": [],
"eventsConsumed": [],
"eventsConsumed": [],
- "namespacesOwned": [],
- "notes": "Providers, models, routing profiles, versioned prompt templates and workflows, runs, request logs, citations, scoped cache, quotas and audit. Workflow output is a draft/evidence package attributed to workflow + model + run. ai.run.queued|succeeded|failed|cached events follow once the Events client is wired in."
+ "namespacesOwned": [
+ "ai.usage_summary"
+ ],
+ "lifecycle": {
+ "liveness": {
+ "endpoint": "/api/health",
+ "means": "the process is up and answers HTTP; it checks nothing else (the database and dependencies are what ready checks)"
+ },
+ "shutdown": {
+ "signal": "SIGTERM",
+ "deadlineSeconds": 10,
+ "drains": [
+ "housekeeping timer, user-module sync and Network key refresh stopped",
+ "open HTTP connections closed (closeAllConnections), then the server",
+ "runs in progress awaited (runs.drain)",
+ "ai.run.* outbox relay stopped after the runs (its send in progress awaited; unsent rows stay for the next start)",
+ "whisper child processes killed",
+ "database closed"
+ ],
+ "note": "the forced exit after 10 s exits 1"
+ },
+ "startupRecovery": {
+ "resumes": [
+ {
+ "kind": "jobs",
+ "what": "runs left queued or running are marked failed with error_code run.interrupted (announced as ai.run.failed); the caller retries them"
+ },
+ {
+ "kind": "outbox",
+ "what": "unsent ai.run.* events in the outbox (server/events.js) go to OpenVibe.Events once the relay starts"
+ }
+ ]
+ },
+ "rollback": {
+ "conditions": [
+ "automatic: ovhost deploy puts the previous sha back and restarts again when the ready URL does not answer 2xx within ready.timeoutSeconds after the restart (exit 3)",
+ "manual: ovhost rollback <service> --to <sha>"
+ ],
+ "window": "automatic only while ovhost waits for readiness after the restart (30 s in host.example.json); manual afterwards, as long as no blocker applies",
+ "blockers": {
+ "none": "the schema code only adds (CREATE … IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
+ }
+ },
+ "contracts": {
+ "range": ">=0.6.0 <1.0.0"
+ },
+ "leases": {
+ "none": "no claims: one process owns ai.db (better-sqlite3, single writer); a run is taken with a compare-and-set on its status (queued → running)"
+ }
+ },
+ "notes": "Providers, models, routing profiles, versioned prompt templates and workflows, runs, request logs, citations, scoped cache, quotas and audit. Workflow output is a draft/evidence package attributed to workflow + model + run. ai.run.queued|succeeded|failed|cached have payload contracts (v0.30.0, status planned): AI publishes them once its Events client is wired in; it publishes none today. ai.run.create takes ai.run-request@1 and returns ai.run@1."
}
}
@@ -12,7 +12,7 @@
@@ -12,7 +12,7 @@
"ajv": "^8.17.1",
"ajv": "^8.17.1",
"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.84.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.86.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
@@ -1448,9 +1448,9 @@
@@ -1448,9 +1448,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.84.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.84.0",
- "integrity": "sha512-wnmQbzffd2xXSGk3Zr1JxZYIL4oSlnJTo8lGpUApBPoDKeQ3U4VCLJgt3cZpbtkbl5NH1qNjBDXkwx+uASwoyA==",
+ "version": "0.86.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.86.0",
+ "integrity": "sha512-3o3AILEBtQ2pK0KqK7GEAlN3HJjaKUl6vrbzEDiBbhK6Nr2hivgN/5MAmJ7WRkgaDkxNsZETs/fLZC2Q4oNCiA==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -24,7 +24,7 @@
@@ -24,7 +24,7 @@
"ajv": "^8.17.1",
"ajv": "^8.17.1",
"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.84.0",
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.86.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
@@ -8,9 +8,10 @@
@@ -8,9 +8,10 @@
* PEM, which skips the fetch entirely.
* PEM, which skips the fetch entirely.
*
*
* 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
- * are proposed in docs/capabilities-proposal/ and are not in openvibe-contracts yet. Until they
- * ship, allows() decides with the contracts' own grant rule (the exact id, or a `family.*` grant);
- * once contracts knows an id, contracts decides.
+ * are proposed in docs/capabilities-proposal/ and are not in openvibe-contracts yet; ai.credential.manage
+ * and ai.quota.attribution.manage ship in contracts (0.73.0 / 0.75.0). Until the five do, allows()
+ * decides with the contracts' own grant rule (the exact id, or a `family.*` grant); once contracts
+ * knows an id, contracts decides.
*
*
* Namespaces fail closed: a token may only run workflows inside the namespaces its `ns` claim holds
* Namespaces fail closed: a token may only run workflows inside the namespaces its `ns` claim holds
* (the same matching as contracts' namespaceAllowed: 'live.*' allows 'live.translate'). A token
* (the same matching as contracts' namespaceAllowed: 'live.*' allows 'live.translate'). A token
@@ -27,6 +28,8 @@ const CAPS = Object.freeze({
@@ -27,6 +28,8 @@ const CAPS = Object.freeze({
workflowManage: 'ai.workflow.manage',
workflowManage: 'ai.workflow.manage',
providerManage: 'ai.provider.manage',
providerManage: 'ai.provider.manage',
usageRead: 'ai.usage.read',
usageRead: 'ai.usage.read',
+ credentialManage: 'ai.credential.manage',
+ quotaAttributionManage: 'ai.quota.attribution.manage',
});
});
/**
/**