openvibers/openvibe.contracts Commits

v0.75.0: per-streamer AI budgets are AI quotas (roadmap WS-O task 2). ai.quota.attribution.manage (first-party): a service caps what runs attributed to one of its own entities may cost or request per hour or day (PUT /api/v1/attribution-quotas/{attribution}, ai.attribution-quota-put@1, optionally for a workflow prefix), reads it with the window's use (ai.attribution-quota@1) or removes it; the attribution's service must be the caller (Live: live:user:<id>). Over the cap a run is refused 429 quota.exceeded before any provider is called.

OP OpenVibers committed 28 Sept 2026 · 8cadcae54e · 39 files, +686 −51


Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 7e36293e..f75eb270 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -6,6 +6,11 @@ the notes were in the tag and commit messages (`git tag -n1`).
## Unreleased
++## 0.75.0 — 2026-09-28
++
++**Per-streamer AI budgets are AI quotas** (roadmap WS-O task 2).
++- `ai.quota.attribution.manage` (first-party): a service caps what runs attributed to one of its own entities may cost or request per hour or day (`PUT /api/v1/attribution-quotas/{attribution}`, `ai.attribution-quota-put@1`, optionally only for workflows under a prefix). It reads the cap with what the window has used (`ai.attribution-quota@1`) or removes it. The attribution's service must be the caller: Live caps `live:user:<id>`, a streamer's daily AI-viewer budget. A run over the cap is refused 429 `quota.exceeded` before any provider is called.
++
## 0.74.0 — 2026-09-28
- `ai.credential-put@1`: `api_key` is optional after the first put. The stored key is kept for a change of models or budget, but must be entered again to change `provider` or `base_url`, so a key never follows a new endpoint on its own (400 `credential.key_required` otherwise). Roadmap WS-O task 2.
ddiff --git a/contracts/ai/attribution-quota-put.v1.json b/contracts/ai/attribution-quota-put.v1.json
nnew file mode 100644
iindex 00000000..efed63ef
---- /dev/null
++++ b/contracts/ai/attribution-quota-put.v1.json
@@@ -0,0 +1,46 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/attribution-quota-put.v1.json",
++ "title": "AiAttributionQuotaPut",
++ "description": "ai.attribution-quota-put@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on runs attributed to one of the caller's own entities, PUT /api/v1/attribution-quotas/{attribution} with capability ai.quota.attribution.manage; the attribution's service must be the caller (Live caps live:user:<id>, a streamer's AI viewers). Over the cap a run is refused 429 quota.exceeded before any provider is called. Cost counts what runs have cost so far in the window, so the run that crosses the cap finishes and the next is refused.",
++ "type": "object",
++ "required": [
++ "window"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "window": {
++ "enum": [
++ "hour",
++ "day"
++ ]
++ },
++ "max_cost_usd": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 10000
++ },
++ "max_requests": {
++ "type": "integer",
++ "minimum": 0,
++ "maximum": 1000000
++ },
++ "workflow_prefix": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_.-]{1,79}$",
++ "description": "Only runs of workflows whose key starts with this (live.viewers.)."
++ }
++ },
++ "anyOf": [
++ {
++ "required": [
++ "max_cost_usd"
++ ]
++ },
++ {
++ "required": [
++ "max_requests"
++ ]
++ }
++ ]
++}
ddiff --git a/contracts/ai/attribution-quota.v1.json b/contracts/ai/attribution-quota.v1.json
nnew file mode 100644
iindex 00000000..848bc307
---- /dev/null
++++ b/contracts/ai/attribution-quota.v1.json
@@@ -0,0 +1,74 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/attribution-quota.v1.json",
++ "title": "AiAttributionQuota",
++ "description": "ai.attribution-quota@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on one attribution as its service reads it (GET or PUT /api/v1/attribution-quotas/{attribution}), with what the current window has used.",
++ "type": "object",
++ "required": [
++ "attribution",
++ "window",
++ "used",
++ "window_resets_at",
++ "updated_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "attribution": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,31}:[a-z][a-z0-9_]{1,31}:[A-Za-z0-9_.-]{1,80}$",
++ "description": "<service>:<type>:<id>, the run's attribution as AI keys it (Live: live:user:<id>)."
++ },
++ "window": {
++ "enum": [
++ "hour",
++ "day"
++ ]
++ },
++ "workflow_prefix": {
++ "type": [
++ "string",
++ "null"
++ ]
++ },
++ "max_cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "max_requests": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "used": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "requests",
++ "cost_usd"
++ ],
++ "properties": {
++ "requests": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0
++ }
++ }
++ },
++ "window_resets_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++}
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex c2b56ee0..ee96b313 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -1223,6 +1223,24 @@
"compatibility": "backward",
"status": "active"
},
++ {
++ "id": "ai.attribution-quota-put",
++ "version": "1.0.0",
++ "owner": "ai",
++ "schema": "ai/attribution-quota-put.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "ai.attribution-quota",
++ "version": "1.0.0",
++ "owner": "ai",
++ "schema": "ai/attribution-quota.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
{
"id": "ai.run-request",
"version": "1.0.0",
ddiff --git a/fixtures/ai.attribution-quota-put/invalid/minute.json b/fixtures/ai.attribution-quota-put/invalid/minute.json
nnew file mode 100644
iindex 00000000..5bf8b4b2
---- /dev/null
++++ b/fixtures/ai.attribution-quota-put/invalid/minute.json
@@@ -0,0 +1 @@
++{"window":"minute","max_requests":5}
ddiff --git a/fixtures/ai.attribution-quota-put/invalid/no-limit.json b/fixtures/ai.attribution-quota-put/invalid/no-limit.json
nnew file mode 100644
iindex 00000000..c1efba66
---- /dev/null
++++ b/fixtures/ai.attribution-quota-put/invalid/no-limit.json
@@@ -0,0 +1 @@
++{"window":"day"}
ddiff --git a/fixtures/ai.attribution-quota-put/valid/viewers-day.json b/fixtures/ai.attribution-quota-put/valid/viewers-day.json
nnew file mode 100644
iindex 00000000..fa2d5e50
---- /dev/null
++++ b/fixtures/ai.attribution-quota-put/valid/viewers-day.json
@@@ -0,0 +1 @@
++{"window":"day","max_cost_usd":0.2,"workflow_prefix":"live.viewers."}
ddiff --git a/fixtures/ai.attribution-quota/invalid/bad-attribution.json b/fixtures/ai.attribution-quota/invalid/bad-attribution.json
nnew file mode 100644
iindex 00000000..04b4c999
---- /dev/null
++++ b/fixtures/ai.attribution-quota/invalid/bad-attribution.json
@@@ -0,0 +1 @@
++{"attribution":"42","window":"day","used":{"requests":0,"cost_usd":0},"window_resets_at":"2026-09-29T00:00:00.000Z","updated_at":"2026-09-28T00:30:00.000Z"}
ddiff --git a/fixtures/ai.attribution-quota/valid/viewers.json b/fixtures/ai.attribution-quota/valid/viewers.json
nnew file mode 100644
iindex 00000000..02a55a40
---- /dev/null
++++ b/fixtures/ai.attribution-quota/valid/viewers.json
@@@ -0,0 +1 @@
++{"attribution":"live:user:42","window":"day","workflow_prefix":"live.viewers.","max_cost_usd":0.2,"max_requests":null,"used":{"requests":12,"cost_usd":0.034},"window_resets_at":"2026-09-29T00:00:00.000Z","updated_at":"2026-09-28T00:30:00.000Z"}
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex 3e2d59eb..a70ae45a 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -12001,6 +12001,136 @@
}
}
},
++ "ai.attribution-quota-put": {
++ "version": "1.0.0",
++ "owner": "ai",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/attribution-quota-put.v1.json",
++ "title": "AiAttributionQuotaPut",
++ "description": "ai.attribution-quota-put@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on runs attributed to one of the caller's own entities, PUT /api/v1/attribution-quotas/{attribution} with capability ai.quota.attribution.manage; the attribution's service must be the caller (Live caps live:user:<id>, a streamer's AI viewers). Over the cap a run is refused 429 quota.exceeded before any provider is called. Cost counts what runs have cost so far in the window, so the run that crosses the cap finishes and the next is refused.",
++ "type": "object",
++ "required": [
++ "window"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "window": {
++ "enum": [
++ "hour",
++ "day"
++ ]
++ },
++ "max_cost_usd": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 10000
++ },
++ "max_requests": {
++ "type": "integer",
++ "minimum": 0,
++ "maximum": 1000000
++ },
++ "workflow_prefix": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_.-]{1,79}$",
++ "description": "Only runs of workflows whose key starts with this (live.viewers.)."
++ }
++ },
++ "anyOf": [
++ {
++ "required": [
++ "max_cost_usd"
++ ]
++ },
++ {
++ "required": [
++ "max_requests"
++ ]
++ }
++ ]
++ }
++ },
++ "ai.attribution-quota": {
++ "version": "1.0.0",
++ "owner": "ai",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/ai/attribution-quota.v1.json",
++ "title": "AiAttributionQuota",
++ "description": "ai.attribution-quota@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on one attribution as its service reads it (GET or PUT /api/v1/attribution-quotas/{attribution}), with what the current window has used.",
++ "type": "object",
++ "required": [
++ "attribution",
++ "window",
++ "used",
++ "window_resets_at",
++ "updated_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "attribution": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,31}:[a-z][a-z0-9_]{1,31}:[A-Za-z0-9_.-]{1,80}$",
++ "description": "<service>:<type>:<id>, the run's attribution as AI keys it (Live: live:user:<id>)."
++ },
++ "window": {
++ "enum": [
++ "hour",
++ "day"
++ ]
++ },
++ "workflow_prefix": {
++ "type": [
++ "string",
++ "null"
++ ]
++ },
++ "max_cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "max_requests": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "used": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "requests",
++ "cost_usd"
++ ],
++ "properties": {
++ "requests": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0
++ }
++ }
++ },
++ "window_resets_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ },
"ai.run-request": {
"version": "1.0.0",
"owner": "ai",
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex f369903c..6df12f18 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
@@@ -16,6 +16,186 @@
}
],
"paths": {
++ "/api/v1/attribution-quotas/{attribution}": {
++ "delete": {
++ "operationId": "delete_api_v1_attribution_quotas_attribution",
++ "summary": "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).",
++ "description": "**ai.quota.attribution.manage** (first-party): 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.",
++ "tags": [
++ "ai.quota"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.quota.attribution.manage"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-quotas",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.quota.attribution.manage"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/ai.attribution-quota-put.v1"
++ },
++ "parameters": [
++ {
++ "name": "attribution",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.attribution-quota.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ },
++ "get": {
++ "operationId": "get_api_v1_attribution_quotas_attribution",
++ "summary": "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).",
++ "description": "**ai.quota.attribution.manage** (first-party): 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.",
++ "tags": [
++ "ai.quota"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.quota.attribution.manage"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-quotas",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.quota.attribution.manage"
++ ]
++ }
++ ],
++ "x-openvibe-input": {
++ "$ref": "#/components/schemas/ai.attribution-quota-put.v1"
++ },
++ "parameters": [
++ {
++ "name": "attribution",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.attribution-quota.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ },
++ "put": {
++ "operationId": "put_api_v1_attribution_quotas_attribution",
++ "summary": "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).",
++ "description": "**ai.quota.attribution.manage** (first-party): 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.",
++ "tags": [
++ "ai.quota"
++ ],
++ "x-openvibe-capabilities": [
++ "ai.quota.attribution.manage"
++ ],
++ "x-openvibe-visibility": [
++ "first-party"
++ ],
++ "x-openvibe-quota-class": "ai-quotas",
++ "security": [
++ {
++ "openvibeToken": [
++ "ai.quota.attribution.manage"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.attribution-quota-put.v1"
++ }
++ }
++ }
++ },
++ "parameters": [
++ {
++ "name": "attribution",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/ai.attribution-quota.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/api/v1/audit": {
"get": {
"operationId": "get_api_v1_audit",
@@@ -2506,6 +2686,122 @@
},
"components": {
"schemas": {
++ "ai.attribution-quota-put.v1": {
++ "title": "AiAttributionQuotaPut",
++ "description": "ai.attribution-quota-put@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on runs attributed to one of the caller's own entities, PUT /api/v1/attribution-quotas/{attribution} with capability ai.quota.attribution.manage; the attribution's service must be the caller (Live caps live:user:<id>, a streamer's AI viewers). Over the cap a run is refused 429 quota.exceeded before any provider is called. Cost counts what runs have cost so far in the window, so the run that crosses the cap finishes and the next is refused.",
++ "type": "object",
++ "required": [
++ "window"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "window": {
++ "enum": [
++ "hour",
++ "day"
++ ]
++ },
++ "max_cost_usd": {
++ "type": "number",
++ "minimum": 0,
++ "maximum": 10000
++ },
++ "max_requests": {
++ "type": "integer",
++ "minimum": 0,
++ "maximum": 1000000
++ },
++ "workflow_prefix": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9_.-]{1,79}$",
++ "description": "Only runs of workflows whose key starts with this (live.viewers.)."
++ }
++ },
++ "anyOf": [
++ {
++ "required": [
++ "max_cost_usd"
++ ]
++ },
++ {
++ "required": [
++ "max_requests"
++ ]
++ }
++ ]
++ },
++ "ai.attribution-quota.v1": {
++ "title": "AiAttributionQuota",
++ "description": "ai.attribution-quota@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on one attribution as its service reads it (GET or PUT /api/v1/attribution-quotas/{attribution}), with what the current window has used.",
++ "type": "object",
++ "required": [
++ "attribution",
++ "window",
++ "used",
++ "window_resets_at",
++ "updated_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "attribution": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,31}:[a-z][a-z0-9_]{1,31}:[A-Za-z0-9_.-]{1,80}$",
++ "description": "<service>:<type>:<id>, the run's attribution as AI keys it (Live: live:user:<id>)."
++ },
++ "window": {
++ "enum": [
++ "hour",
++ "day"
++ ]
++ },
++ "workflow_prefix": {
++ "type": [
++ "string",
++ "null"
++ ]
++ },
++ "max_cost_usd": {
++ "type": [
++ "number",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "max_requests": {
++ "type": [
++ "integer",
++ "null"
++ ],
++ "minimum": 0
++ },
++ "used": {
++ "type": "object",
++ "additionalProperties": false,
++ "required": [
++ "requests",
++ "cost_usd"
++ ],
++ "properties": {
++ "requests": {
++ "type": "integer",
++ "minimum": 0
++ },
++ "cost_usd": {
++ "type": "number",
++ "minimum": 0
++ }
++ }
++ },
++ "window_resets_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ },
"ai.credential-put.v1": {
"title": "AiCredentialPut",
"description": "ai.credential-put@1 (OpenVibe.AI; roadmap WS-O task 2): a person's own provider key, stored by the service that holds their consent (Live, for a streamer's AI viewers), PUT /api/v1/credentials/{subject} with capability ai.credential.manage. OpenVibe.AI encrypts the key at rest and never returns it; runs that name the credential call that provider with it, never a shared key, and are limited by `budget_usd_per_day`. `base_url` is any https endpoint (OpenAI-compatible or Anthropic); OpenVibe.AI connects only to public addresses.",
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex d34964e4..01622760 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex 19874771..1c76974f 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex abffe1d5..440b56fc 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex 6c586574..8a133ac6 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex 5c76ba3e..a991397c 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex a26eca79..96ffbc28 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex 351c8c38..19684b1f 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex 19f534c8..a9a4935a 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex 232d84ea..517c49ad 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex ff11a4fe..32a209ac 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/index.json b/generated/openapi/index.json
iindex f0046182..1bc43e8a 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -5,8 +5,8 @@
"service": "ai",
"name": "OpenVibe.AI",
"origin": "https://ai.openvibe.network",
-- "operations": 40,
-- "capabilities": 6
++ "operations": 43,
++ "capabilities": 7
},
{
"service": "billing",
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 9bfdb768..4a5983eb 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex c665b716..3260257b 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 0bd3c84e..d2ec45ed 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex c530467e..2cc8a5ca 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex 88b8f62f..8dff803b 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRe.Stream API",
-- "version": "0.74.0",
-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex ec314ff6..2b955519 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex 5b88184d..779feb92 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex 8f3a78da..a458ea7c 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex 9c408d5c..192ca693 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex 627379c8..68495dc1 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex cf909023..46d5916c 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex aba6c9ab..066274bb 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex aa983ac3..282ec327 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.74.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.74.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.75.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.75.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex 1f57f169..c314a45d 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -15829,6 +15829,43 @@ export interface AiCredential {
last_used_at?: string | null;
}
++/** [email protected] (owner: ai) */
++/**
++ * ai.attribution-quota-put@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on runs attributed to one of the caller's own entities, PUT /api/v1/attribution-quotas/{attribution} with capability ai.quota.attribution.manage; the attribution's service must be the caller (Live caps live:user:<id>, a streamer's AI viewers). Over the cap a run is refused 429 quota.exceeded before any provider is called. Cost counts what runs have cost so far in the window, so the run that crosses the cap finishes and the next is refused.
++ */
++export type AiAttributionQuotaPut = {
++ [k: string]: unknown | undefined;
++} & {
++ window: "hour" | "day";
++ max_cost_usd?: number;
++ max_requests?: number;
++ /**
++ * Only runs of workflows whose key starts with this (live.viewers.).
++ */
++ workflow_prefix?: string;
++};
++
++/** [email protected] (owner: ai) */
++/**
++ * ai.attribution-quota@1 (OpenVibe.AI; roadmap WS-O task 2): a cap on one attribution as its service reads it (GET or PUT /api/v1/attribution-quotas/{attribution}), with what the current window has used.
++ */
++export interface AiAttributionQuota {
++ /**
++ * <service>:<type>:<id>, the run's attribution as AI keys it (Live: live:user:<id>).
++ */
++ attribution: string;
++ window: "hour" | "day";
++ workflow_prefix?: string | null;
++ max_cost_usd?: number | null;
++ max_requests?: number | null;
++ used: {
++ requests: number;
++ cost_usd: number;
++ };
++ window_resets_at: string;
++ updated_at: string;
++}
++
/** [email protected] (owner: ai) */
/**
* Body of POST /api/v1/runs on OpenVibe.AI (capability ai.run.create; ADR-015). Runs the newest active version of a workflow (or the given active or deprecated version) on input that must match that workflow version's own input schema; per-workflow input and output schemas live in AI's registry (GET /api/v1/workflows/:key), not here. The token's ns claim limits which workflow namespaces may run (403 capability.namespace_denied). ?wait=ms waits for the result: 201 finished or served from cache, 202 still queued/running (poll GET /api/v1/runs/:id), 200 an idempotent replay. Errors are problem+json: 404 workflow.not_found, 409 workflow.inactive, 409 idempotency.conflict, 413 input.too_large, 422 input.invalid, 429 quota.exceeded or queue.full with Retry-After. The direct operations POST /api/v1/{chat,generate,summarize,classify,extract,enrich,embed} take the same fields (except workflow and version) with the input fields at the top level and run workflow ai.<op>. target (EntityRef): what the output is about, part of the cache scope and a run filter. attribution (EntityRef): what the spend is attributed to for quotas and usage. on_behalf_of (SubjectRef): the person or actor the caller acts for, part of the cache scope and per-actor quotas.
ddiff --git a/manifests/capabilities/ai.quota.attribution.manage.json b/manifests/capabilities/ai.quota.attribution.manage.json
nnew file mode 100644
iindex 00000000..10003108
---- /dev/null
++++ b/manifests/capabilities/ai.quota.attribution.manage.json
@@@ -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"
++}
ddiff --git a/manifests/services/ai.json b/manifests/services/ai.json
iindex b98fc7ca..9f4e3f61 100644
---- a/manifests/services/ai.json
++++ b/manifests/services/ai.json
@@@ -22,6 +22,7 @@
"capabilities": [
"ai.credential.manage",
"ai.provider.manage",
++ "ai.quota.attribution.manage",
"ai.run.create",
"ai.run.read",
"ai.usage.read",
ddiff --git a/package.json b/package.json
iindex 92c0eeb9..940d7489 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.74.0",
++ "version": "0.75.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",