openvibers/openvibe.codes Commits
Add a validated harness offer catalog (#5)
Changes
@@@ -7,3 +7,4 @@ dist/*.log*.pem*.key++!server/data/nnew file mode 100644@@@ -0,0 +1,181 @@++[++ {++ "id": "claude-code",++ "name": "Claude Code",++ "provider": "anthropic",++ "capabilities": {++ "host_access": true,++ "mcp": true,++ "long_autonomy": true,++ "resume": true++ },++ "address": {++ "kind": "cli",++ "target": "claude"++ },++ "price": {++ "amount_usd": 0,++ "unit": "hour"++ },++ "limits": {++ "max_duration_seconds": 14400,++ "max_concurrent_runs": 4,++ "max_context_tokens": 200000++ },++ "agents": [++ {++ "id": "claude-code-sonnet",++ "harness": "claude-code",++ "provider": "anthropic",++ "model": "claude-sonnet-5-5",++ "context_limits": {++ "input_tokens": 200000,++ "output_tokens": 64000++ },++ "concurrency": 4,++ "price_per_1k_tokens": {++ "fresh_usd": 0,++ "cached_usd": 0,++ "output_usd": 0++ },++ "availability_windows": []++ }++ ]++ },++ {++ "id": "codex",++ "name": "Codex",++ "provider": "openai",++ "capabilities": {++ "host_access": true,++ "mcp": true,++ "long_autonomy": true,++ "resume": true++ },++ "address": {++ "kind": "cli",++ "target": "codex"++ },++ "price": {++ "amount_usd": 0,++ "unit": "hour"++ },++ "limits": {++ "max_duration_seconds": 14400,++ "max_concurrent_runs": 4,++ "max_context_tokens": 200000++ },++ "agents": [++ {++ "id": "codex-default",++ "harness": "codex",++ "provider": "openai",++ "model": "codex",++ "context_limits": {++ "input_tokens": 200000,++ "output_tokens": 32000++ },++ "concurrency": 4,++ "price_per_1k_tokens": {++ "fresh_usd": 0,++ "cached_usd": 0,++ "output_usd": 0++ },++ "availability_windows": []++ }++ ]++ },++ {++ "id": "command-code",++ "name": "Command Code",++ "provider": "commandcode",++ "capabilities": {++ "host_access": true,++ "mcp": true,++ "long_autonomy": false,++ "resume": true++ },++ "address": {++ "kind": "cli",++ "target": "cmd"++ },++ "price": {++ "amount_usd": 0,++ "unit": "hour"++ },++ "limits": {++ "max_duration_seconds": 7200,++ "max_concurrent_runs": 2,++ "max_context_tokens": 128000++ },++ "agents": []++ },++ {++ "id": "aider",++ "name": "Aider",++ "provider": "aider",++ "capabilities": {++ "host_access": true,++ "mcp": false,++ "long_autonomy": false,++ "resume": true++ },++ "address": {++ "kind": "cli",++ "target": "aider"++ },++ "price": {++ "amount_usd": 0,++ "unit": "hour"++ },++ "limits": {++ "max_duration_seconds": 7200,++ "max_concurrent_runs": 2,++ "max_context_tokens": 128000++ },++ "agents": []++ },++ {++ "id": "deepseek",++ "name": "DeepSeek",++ "provider": "deepseek",++ "capabilities": {++ "host_access": false,++ "mcp": false,++ "long_autonomy": false,++ "resume": false++ },++ "address": {++ "kind": "api",++ "target": "https://api.deepseek.com"++ },++ "price": {++ "amount_usd": 0,++ "unit": "hour"++ },++ "limits": {++ "max_duration_seconds": 3600,++ "max_concurrent_runs": 8,++ "max_context_tokens": 64000++ },++ "agents": [++ {++ "id": "deepseek-chat",++ "harness": "deepseek",++ "provider": "deepseek",++ "model": "deepseek-chat",++ "context_limits": {++ "input_tokens": 64000,++ "output_tokens": 8192++ },++ "concurrency": 8,++ "price_per_1k_tokens": {++ "fresh_usd": 0,++ "cached_usd": 0,++ "output_usd": 0++ },++ "availability_windows": []++ }++ ]++ }++]nnew file mode 100644@@@ -0,0 +1,51 @@++'use strict';++++/** Static harness catalog. Replace the file reader when offer ownership is settled. */++const fs = require('fs');++const path = require('path');++const contracts = require('openvibe-contracts');++++const DEFAULT_CATALOG = path.join(__dirname, '..', 'data', 'harness-offers.json');++++function invalid(detail) {++ const error = new Error(`invalid harness catalog: ${detail}`);++ error.code = 'harness.invalid';++ return error;++}++++function createHarnesses({ catalogPath = DEFAULT_CATALOG } = {}) {++ let rows;++ try {++ rows = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));++ } catch (error) {++ throw invalid(error.message);++ }++ if (!Array.isArray(rows)) throw invalid('expected an array of offers');++++ const byId = new Map();++ const ids = new Set();++ for (const [index, row] of rows.entries()) {++ if (!row || typeof row !== 'object' || Array.isArray(row)) throw invalid(`row ${index} is not an offer`);++ const { agents, ...offer } = row;++ const harnessCheck = contracts.validate('platform.harness-offer@1', offer);++ if (!harnessCheck.valid) throw invalid(`row ${index} harness offer: ${JSON.stringify(harnessCheck.errors)}`);++ if (ids.has(offer.id)) throw invalid(`duplicate id ${offer.id}`);++ ids.add(offer.id);++ if (!Array.isArray(agents)) throw invalid(`row ${index} needs agents[]`);++ for (const [agentIndex, agent] of agents.entries()) {++ const agentCheck = contracts.validate('platform.agent-offer@1', agent);++ if (!agentCheck.valid) throw invalid(`row ${index} agent ${agentIndex}: ${JSON.stringify(agentCheck.errors)}`);++ if (ids.has(agent.id)) throw invalid(`duplicate id ${agent.id}`);++ if (agent.harness !== offer.id) throw invalid(`agent ${agent.id} refers to another harness`);++ ids.add(agent.id);++ }++ byId.set(offer.id, row);++ }++++ const get = (id) => byId.get(id) || null;++ const list = () => [...byId.values()];++ const agents = (id) => get(id)?.agents || [];++ return { list, get, agents };++}++++module.exports = { createHarnesses };nnew file mode 100644@@@ -0,0 +1,65 @@++'use strict';++++const assert = require('assert');++const fs = require('fs');++const os = require('os');++const path = require('path');++const contracts = require('openvibe-contracts');++const { createHarnesses } = require('../server/domain/harnesses');++const { check, done } = require('./helpers/boot');++++const catalogPath = path.join(__dirname, '..', 'server', 'data', 'harness-offers.json');++const rows = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));++++(async () => {++ await check('every seed row matches the pinned harness and agent contracts', async () => {++ assert.strictEqual(rows.length, 5);++ for (const { agents, ...offer } of rows) {++ const harnessCheck = contracts.validate('platform.harness-offer@1', offer);++ assert.strictEqual(harnessCheck.valid, true, JSON.stringify(harnessCheck.errors));++ assert.ok(Array.isArray(agents));++ for (const agent of agents) {++ const agentCheck = contracts.validate('platform.agent-offer@1', agent);++ assert.strictEqual(agentCheck.valid, true, JSON.stringify(agentCheck.errors));++ assert.strictEqual(agent.harness, offer.id);++ }++ }++ });++++ await check('harness and agent ids are unique', async () => {++ const ids = rows.flatMap((row) => [row.id, ...row.agents.map((agent) => agent.id)]);++ assert.strictEqual(new Set(ids).size, ids.length);++ });++++ await check('list, get and agents round-trip the catalog', async () => {++ const harnesses = createHarnesses({ catalogPath });++ assert.deepStrictEqual(harnesses.list(), rows);++ for (const row of rows) {++ assert.deepStrictEqual(harnesses.get(row.id), row);++ assert.deepStrictEqual(harnesses.agents(row.id), row.agents);++ }++ assert.strictEqual(harnesses.get('missing'), null);++ assert.deepStrictEqual(harnesses.agents('missing'), []);++ });++++ await check('malformed offers, malformed agents and duplicate ids are rejected', async () => {++ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'codes-harnesses-'));++ const badPath = path.join(dir, 'offers.json');++ const expectInvalid = (data) => {++ fs.writeFileSync(badPath, JSON.stringify(data));++ assert.throws(() => createHarnesses({ catalogPath: badPath }), (error) => error.code === 'harness.invalid');++ };++ try {++ expectInvalid([{ ...rows[0], unexpected: true }]);++ expectInvalid([{ ...rows[0], agents: [{ ...rows[0].agents[0], unexpected: true }] }]);++ expectInvalid([rows[0], rows[0]]);++ expectInvalid([{ ...rows[0], agents: [rows[0].agents[0], rows[0].agents[0]] }]);++ expectInvalid([{ ...rows[0], agents: [{ ...rows[0].agents[0], harness: 'other' }] }]);++ } finally {++ fs.unlinkSync(badPath);++ fs.rmdirSync(dir);++ }++ });++++ done();++})();
@@ -7,3 +7,4 @@ dist/
@@ -7,3 +7,4 @@ dist/
*.log
*.log
*.pem
*.pem
*.key
*.key
+!server/data/
new file mode 100644
new file mode 100644
@@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
+[
+ {
+ "id": "claude-code",
+ "name": "Claude Code",
+ "provider": "anthropic",
+ "capabilities": {
+ "host_access": true,
+ "mcp": true,
+ "long_autonomy": true,
+ "resume": true
+ },
+ "address": {
+ "kind": "cli",
+ "target": "claude"
+ },
+ "price": {
+ "amount_usd": 0,
+ "unit": "hour"
+ },
+ "limits": {
+ "max_duration_seconds": 14400,
+ "max_concurrent_runs": 4,
+ "max_context_tokens": 200000
+ },
+ "agents": [
+ {
+ "id": "claude-code-sonnet",
+ "harness": "claude-code",
+ "provider": "anthropic",
+ "model": "claude-sonnet-5-5",
+ "context_limits": {
+ "input_tokens": 200000,
+ "output_tokens": 64000
+ },
+ "concurrency": 4,
+ "price_per_1k_tokens": {
+ "fresh_usd": 0,
+ "cached_usd": 0,
+ "output_usd": 0
+ },
+ "availability_windows": []
+ }
+ ]
+ },
+ {
+ "id": "codex",
+ "name": "Codex",
+ "provider": "openai",
+ "capabilities": {
+ "host_access": true,
+ "mcp": true,
+ "long_autonomy": true,
+ "resume": true
+ },
+ "address": {
+ "kind": "cli",
+ "target": "codex"
+ },
+ "price": {
+ "amount_usd": 0,
+ "unit": "hour"
+ },
+ "limits": {
+ "max_duration_seconds": 14400,
+ "max_concurrent_runs": 4,
+ "max_context_tokens": 200000
+ },
+ "agents": [
+ {
+ "id": "codex-default",
+ "harness": "codex",
+ "provider": "openai",
+ "model": "codex",
+ "context_limits": {
+ "input_tokens": 200000,
+ "output_tokens": 32000
+ },
+ "concurrency": 4,
+ "price_per_1k_tokens": {
+ "fresh_usd": 0,
+ "cached_usd": 0,
+ "output_usd": 0
+ },
+ "availability_windows": []
+ }
+ ]
+ },
+ {
+ "id": "command-code",
+ "name": "Command Code",
+ "provider": "commandcode",
+ "capabilities": {
+ "host_access": true,
+ "mcp": true,
+ "long_autonomy": false,
+ "resume": true
+ },
+ "address": {
+ "kind": "cli",
+ "target": "cmd"
+ },
+ "price": {
+ "amount_usd": 0,
+ "unit": "hour"
+ },
+ "limits": {
+ "max_duration_seconds": 7200,
+ "max_concurrent_runs": 2,
+ "max_context_tokens": 128000
+ },
+ "agents": []
+ },
+ {
+ "id": "aider",
+ "name": "Aider",
+ "provider": "aider",
+ "capabilities": {
+ "host_access": true,
+ "mcp": false,
+ "long_autonomy": false,
+ "resume": true
+ },
+ "address": {
+ "kind": "cli",
+ "target": "aider"
+ },
+ "price": {
+ "amount_usd": 0,
+ "unit": "hour"
+ },
+ "limits": {
+ "max_duration_seconds": 7200,
+ "max_concurrent_runs": 2,
+ "max_context_tokens": 128000
+ },
+ "agents": []
+ },
+ {
+ "id": "deepseek",
+ "name": "DeepSeek",
+ "provider": "deepseek",
+ "capabilities": {
+ "host_access": false,
+ "mcp": false,
+ "long_autonomy": false,
+ "resume": false
+ },
+ "address": {
+ "kind": "api",
+ "target": "https://api.deepseek.com"
+ },
+ "price": {
+ "amount_usd": 0,
+ "unit": "hour"
+ },
+ "limits": {
+ "max_duration_seconds": 3600,
+ "max_concurrent_runs": 8,
+ "max_context_tokens": 64000
+ },
+ "agents": [
+ {
+ "id": "deepseek-chat",
+ "harness": "deepseek",
+ "provider": "deepseek",
+ "model": "deepseek-chat",
+ "context_limits": {
+ "input_tokens": 64000,
+ "output_tokens": 8192
+ },
+ "concurrency": 8,
+ "price_per_1k_tokens": {
+ "fresh_usd": 0,
+ "cached_usd": 0,
+ "output_usd": 0
+ },
+ "availability_windows": []
+ }
+ ]
+ }
+]
new file mode 100644
new file mode 100644
@@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
+'use strict';
+
+/** Static harness catalog. Replace the file reader when offer ownership is settled. */
+const fs = require('fs');
+const path = require('path');
+const contracts = require('openvibe-contracts');
+
+const DEFAULT_CATALOG = path.join(__dirname, '..', 'data', 'harness-offers.json');
+
+function invalid(detail) {
+ const error = new Error(`invalid harness catalog: ${detail}`);
+ error.code = 'harness.invalid';
+ return error;
+}
+
+function createHarnesses({ catalogPath = DEFAULT_CATALOG } = {}) {
+ let rows;
+ try {
+ rows = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
+ } catch (error) {
+ throw invalid(error.message);
+ }
+ if (!Array.isArray(rows)) throw invalid('expected an array of offers');
+
+ const byId = new Map();
+ const ids = new Set();
+ for (const [index, row] of rows.entries()) {
+ if (!row || typeof row !== 'object' || Array.isArray(row)) throw invalid(`row ${index} is not an offer`);
+ const { agents, ...offer } = row;
+ const harnessCheck = contracts.validate('platform.harness-offer@1', offer);
+ if (!harnessCheck.valid) throw invalid(`row ${index} harness offer: ${JSON.stringify(harnessCheck.errors)}`);
+ if (ids.has(offer.id)) throw invalid(`duplicate id ${offer.id}`);
+ ids.add(offer.id);
+ if (!Array.isArray(agents)) throw invalid(`row ${index} needs agents[]`);
+ for (const [agentIndex, agent] of agents.entries()) {
+ const agentCheck = contracts.validate('platform.agent-offer@1', agent);
+ if (!agentCheck.valid) throw invalid(`row ${index} agent ${agentIndex}: ${JSON.stringify(agentCheck.errors)}`);
+ if (ids.has(agent.id)) throw invalid(`duplicate id ${agent.id}`);
+ if (agent.harness !== offer.id) throw invalid(`agent ${agent.id} refers to another harness`);
+ ids.add(agent.id);
+ }
+ byId.set(offer.id, row);
+ }
+
+ const get = (id) => byId.get(id) || null;
+ const list = () => [...byId.values()];
+ const agents = (id) => get(id)?.agents || [];
+ return { list, get, agents };
+}
+
+module.exports = { createHarnesses };
new file mode 100644
new file mode 100644
@@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
+'use strict';
+
+const assert = require('assert');
+const fs = require('fs');
+const os = require('os');
+const path = require('path');
+const contracts = require('openvibe-contracts');
+const { createHarnesses } = require('../server/domain/harnesses');
+const { check, done } = require('./helpers/boot');
+
+const catalogPath = path.join(__dirname, '..', 'server', 'data', 'harness-offers.json');
+const rows = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
+
+(async () => {
+ await check('every seed row matches the pinned harness and agent contracts', async () => {
+ assert.strictEqual(rows.length, 5);
+ for (const { agents, ...offer } of rows) {
+ const harnessCheck = contracts.validate('platform.harness-offer@1', offer);
+ assert.strictEqual(harnessCheck.valid, true, JSON.stringify(harnessCheck.errors));
+ assert.ok(Array.isArray(agents));
+ for (const agent of agents) {
+ const agentCheck = contracts.validate('platform.agent-offer@1', agent);
+ assert.strictEqual(agentCheck.valid, true, JSON.stringify(agentCheck.errors));
+ assert.strictEqual(agent.harness, offer.id);
+ }
+ }
+ });
+
+ await check('harness and agent ids are unique', async () => {
+ const ids = rows.flatMap((row) => [row.id, ...row.agents.map((agent) => agent.id)]);
+ assert.strictEqual(new Set(ids).size, ids.length);
+ });
+
+ await check('list, get and agents round-trip the catalog', async () => {
+ const harnesses = createHarnesses({ catalogPath });
+ assert.deepStrictEqual(harnesses.list(), rows);
+ for (const row of rows) {
+ assert.deepStrictEqual(harnesses.get(row.id), row);
+ assert.deepStrictEqual(harnesses.agents(row.id), row.agents);
+ }
+ assert.strictEqual(harnesses.get('missing'), null);
+ assert.deepStrictEqual(harnesses.agents('missing'), []);
+ });
+
+ await check('malformed offers, malformed agents and duplicate ids are rejected', async () => {
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'codes-harnesses-'));
+ const badPath = path.join(dir, 'offers.json');
+ const expectInvalid = (data) => {
+ fs.writeFileSync(badPath, JSON.stringify(data));
+ assert.throws(() => createHarnesses({ catalogPath: badPath }), (error) => error.code === 'harness.invalid');
+ };
+ try {
+ expectInvalid([{ ...rows[0], unexpected: true }]);
+ expectInvalid([{ ...rows[0], agents: [{ ...rows[0].agents[0], unexpected: true }] }]);
+ expectInvalid([rows[0], rows[0]]);
+ expectInvalid([{ ...rows[0], agents: [rows[0].agents[0], rows[0].agents[0]] }]);
+ expectInvalid([{ ...rows[0], agents: [{ ...rows[0].agents[0], harness: 'other' }] }]);
+ } finally {
+ fs.unlinkSync(badPath);
+ fs.rmdirSync(dir);
+ }
+ });
+
+ done();
+})();