openvibers/openvibe.ai Commits

Relay AI usage samples to local Billing by default (#470)

OP OpenVibers committed 2 days ago · 5e6ac33d6a · 3 files, +21 −3

Changes

ddiff --git a/.env.example b/.env.example
iindex 3f9debb..c1d6c88 100644
---- a/.env.example
++++ b/.env.example
@@@ -66,7 +66,8 @@ OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000
# ── Billing (plan T5 lane F) ──
# One platform.usage-sample@1 reading per accounted run, posted to billing.usage.record with AI's
# service token, so Network must grant client `ai` billing.usage.record on openvibe.billing. Readings
--# are queued from the start and sent while OV_BILLING_INTERNAL_URL is set; USAGE_SAMPLES=off stops queueing them.
++# are queued from the start. In production they are sent to colocated Billing at 127.0.0.1:4600 by
++# default; OV_BILLING_INTERNAL_URL overrides the address, and USAGE_SAMPLES=off stops queueing them.
#OV_BILLING_INTERNAL_URL=http://127.0.0.1:4600
#USAGE_SAMPLES=on
#USAGE_SAMPLES_INTERVAL_MS=2000
ddiff --git a/server/config.js b/server/config.js
iindex df379da..84d731e 100644
---- a/server/config.js
++++ b/server/config.js
@@@ -537,12 +537,13 @@ function load(env = process.env) {
// ── Billing (plan T5 lane F): one platform.usage-sample@1 reading per accounted run, posted by
// server/usage-samples.js to billing.usage.record (POST /api/v1/usage, audience openvibe.billing).
-- // Readings are queued unless USAGE_SAMPLES=off; they are sent while OV_BILLING_INTERNAL_URL is set.
++ // Readings are queued unless USAGE_SAMPLES=off. Production's colocated Billing receives them by
++ // default; OV_BILLING_INTERNAL_URL overrides that address when the services are split.
// No `capability:` key: AI asks for billing.usage.record (named in usage-samples.js), Billing enforces it,
// and openvibe-contracts-check reads a `capability: 'x'` literal as one this service enforces.
billing: {
enabled: bool(env.USAGE_SAMPLES, true),
-- billingUrl: trimUrl(env.OV_BILLING_INTERNAL_URL),
++ billingUrl: trimUrl(env.OV_BILLING_INTERNAL_URL != null ? env.OV_BILLING_INTERNAL_URL : (isProduction ? 'http://127.0.0.1:4600' : '')),
audience: 'openvibe.billing',
intervalMs: Math.max(100, int(env.USAGE_SAMPLES_INTERVAL_MS, 2000)),
},
ddiff --git a/test/billing-config.test.js b/test/billing-config.test.js
nnew file mode 100644
iindex 0000000..a2f51fe
---- /dev/null
++++ b/test/billing-config.test.js
@@@ -0,0 +1,16 @@
++'use strict';
++const assert = require('assert');
++const { load } = require('../server/config');
++const { suite } = require('./helpers');
++
++const t = suite('billing-config');
++
++t.test('production relays usage to colocated Billing unless overridden or disabled', () => {
++ assert.strictEqual(load({ NODE_ENV: 'production' }).billing.billingUrl, 'http://127.0.0.1:4600');
++ assert.strictEqual(load({ NODE_ENV: 'development' }).billing.billingUrl, '');
++ assert.strictEqual(load({ NODE_ENV: 'production', OV_BILLING_INTERNAL_URL: 'https://billing.example/' }).billing.billingUrl, 'https://billing.example');
++ assert.strictEqual(load({ NODE_ENV: 'production', OV_BILLING_INTERNAL_URL: '' }).billing.billingUrl, '');
++ assert.strictEqual(load({ NODE_ENV: 'production', USAGE_SAMPLES: 'off' }).billing.enabled, false);
++});
++
++t.run();