openvibers/openvibe.ai Commits
Prepare Claude Opus for owner-configured icon generation (#473)
Changes
@@@ -739,7 +739,19 @@ const PROVIDERS = [{ key: 'deepseek', keys_url: 'https://platform.deepseek.com/api_keys', display_name: 'DeepSeek', base_url: 'https://api.deepseek.com/v1', default_model: 'deepseek-flash',docs_url: 'https://api-docs.deepseek.com/', capabilities: ['chat', 'vision', 'tools', 'web-search'], search_adapters: ['deepseek'] },{ key: 'anthropic', keys_url: 'https://console.anthropic.com/settings/keys', display_name: 'Anthropic', kind: 'anthropic', base_url: 'https://api.anthropic.com/v1', auth_mode: 'x-api-key',-- docs_url: 'https://platform.claude.com/docs/en/api/overview', capabilities: ['chat', 'messages', 'vision', 'tools'] },++ docs_url: 'https://platform.claude.com/docs/en/api/overview', capabilities: ['chat', 'messages', 'vision', 'tools'],++ default_model: 'claude-opus-5-5',++ // Design's signed-in icon task names this model. The provider remains disabled and UNVERIFIED until++ // the owner supplies a key and confirms the commercial access and retail price.++ models: [{++ model_key: 'claude-opus-5-5', display_name: 'Claude Opus 5.5', family: 'claude',++ context_window: 1000000, max_output: 128000,++ cost: { in_per_mtok: 4, cached_per_mtok: 0.2, out_per_mtok: 20 },++ source: 'https://platform.claude.com/docs/en/models/opus-5-5/overview', checked: '2026-11-11',++ supports: { json: true, tools: true, streaming: true, vision: true },++ quantization: null, refusal_rate: null,++ }],++ },{ key: 'openai', keys_url: 'https://platform.openai.com/api-keys', display_name: 'OpenAI', base_url: 'https://api.openai.com/v1', default_model: 'gpt-5-mini',docs_url: 'https://platform.openai.com/docs/api-reference/models/list', capabilities: ['chat', 'vision', 'tools', 'image', 'video', 'speech', 'transcribe', 'embed'] },{ key: 'gemini', models_dev_id: 'google', keys_url: 'https://aistudio.google.com/apikey', display_name: 'Google AI Studio (Gemini API)', base_url: 'https://generativelanguage.googleapis.com/v1beta/openai',@@@ -35,7 +35,7 @@ const DOMAIN = {fireworks: 'fireworks.ai', groq: 'groq.com', cerebras: 'cerebras.ai', sambanova: 'sambanova.ai',baseten: 'baseten.co', hyperbolic: 'hyperbolic.xyz', parasail: 'parasail.io', 'particle-ai': 'particle.ai','inference-net': 'inference.net', 'atlas-cloud': 'atlascloud.ai', avian: 'avian.io',-- nanogpt: 'nano-gpt.com', infermatic: 'totalgpt.ai', arliai: 'arliai.com', friendli: 'friendli.ai', scaleway: 'scaleway.com',++ nanogpt: 'nano-gpt.com', infermatic: 'totalgpt.ai', arliai: 'arliai.com', friendli: 'friendli.ai', scaleway: 'scaleway.com', anthropic: 'claude.com',iteracompute: 'iteracompute.com', sable: 'sableapi.com', inception: 'inceptionlabs.ai', dosai: 'dos.ai', 'runpod-vllm': 'runpod.io', meta: 'meta.ai',};const onItsOwnSite = (url, key) => {nnew file mode 100644@@@ -0,0 +1,31 @@++'use strict';++const assert = require('node:assert/strict');++const { boot, request, suite } = require('./helpers');++const { byKey } = require('../server/providers/pool-providers');++const { recordOf, modelOf } = require('../server/providers/pool-seed');++++const t = suite('anthropic-catalog');++const anthropic = byKey.get('anthropic');++const opus = anthropic.models.find((model) => model.model_key === 'claude-opus-5-5');++let h;++++t.test('the Design model has an owner key slot and a sourced rate, but starts off', () => {++ assert.equal(anthropic.default_model, opus.model_key);++ assert.equal(recordOf(anthropic).status, 'disabled');++ assert.equal(recordOf(anthropic).secret_ref, 'vault:anthropic');++ assert.equal(recordOf(anthropic).provider_access, 'UNVERIFIED');++ assert.deepEqual([modelOf(anthropic, opus).cost.in_per_mtok, modelOf(anthropic, opus).cost.out_per_mtok], [4, 20]);++ assert.match(opus.source, /^https:\/\/platform\.claude\.com\/docs\/en\/models\/opus-5-5\//);++});++++t.test('the model is seeded for owner configuration but a disabled provider is absent from public offers', async () => {++ h = await boot();++ assert.equal((await h.registry.getProvider('anthropic')).status, 'disabled');++ assert.ok(await h.registry.getModel('anthropic', opus.model_key));++ const r = await request(h.base, 'GET', '/api/v1/exchange/catalog');++ assert.equal(r.status, 200);++ assert.ok(!r.body.models.some((model) => model.canonical === 'anthropic/claude-opus-5-5'));++});++++t.test('stop', async () => { if (h) await h.stop(); });++t.run();
@@ -739,7 +739,19 @@ const PROVIDERS = [
@@ -739,7 +739,19 @@ const PROVIDERS = [
{ key: 'deepseek', keys_url: 'https://platform.deepseek.com/api_keys', display_name: 'DeepSeek', base_url: 'https://api.deepseek.com/v1', default_model: 'deepseek-flash',
{ key: 'deepseek', keys_url: 'https://platform.deepseek.com/api_keys', display_name: 'DeepSeek', base_url: 'https://api.deepseek.com/v1', default_model: 'deepseek-flash',
docs_url: 'https://api-docs.deepseek.com/', capabilities: ['chat', 'vision', 'tools', 'web-search'], search_adapters: ['deepseek'] },
docs_url: 'https://api-docs.deepseek.com/', capabilities: ['chat', 'vision', 'tools', 'web-search'], search_adapters: ['deepseek'] },
{ key: 'anthropic', keys_url: 'https://console.anthropic.com/settings/keys', display_name: 'Anthropic', kind: 'anthropic', base_url: 'https://api.anthropic.com/v1', auth_mode: 'x-api-key',
{ key: 'anthropic', keys_url: 'https://console.anthropic.com/settings/keys', display_name: 'Anthropic', kind: 'anthropic', base_url: 'https://api.anthropic.com/v1', auth_mode: 'x-api-key',
- docs_url: 'https://platform.claude.com/docs/en/api/overview', capabilities: ['chat', 'messages', 'vision', 'tools'] },
+ docs_url: 'https://platform.claude.com/docs/en/api/overview', capabilities: ['chat', 'messages', 'vision', 'tools'],
+ default_model: 'claude-opus-5-5',
+ // Design's signed-in icon task names this model. The provider remains disabled and UNVERIFIED until
+ // the owner supplies a key and confirms the commercial access and retail price.
+ models: [{
+ model_key: 'claude-opus-5-5', display_name: 'Claude Opus 5.5', family: 'claude',
+ context_window: 1000000, max_output: 128000,
+ cost: { in_per_mtok: 4, cached_per_mtok: 0.2, out_per_mtok: 20 },
+ source: 'https://platform.claude.com/docs/en/models/opus-5-5/overview', checked: '2026-11-11',
+ supports: { json: true, tools: true, streaming: true, vision: true },
+ quantization: null, refusal_rate: null,
+ }],
+ },
{ key: 'openai', keys_url: 'https://platform.openai.com/api-keys', display_name: 'OpenAI', base_url: 'https://api.openai.com/v1', default_model: 'gpt-5-mini',
{ key: 'openai', keys_url: 'https://platform.openai.com/api-keys', display_name: 'OpenAI', base_url: 'https://api.openai.com/v1', default_model: 'gpt-5-mini',
docs_url: 'https://platform.openai.com/docs/api-reference/models/list', capabilities: ['chat', 'vision', 'tools', 'image', 'video', 'speech', 'transcribe', 'embed'] },
docs_url: 'https://platform.openai.com/docs/api-reference/models/list', capabilities: ['chat', 'vision', 'tools', 'image', 'video', 'speech', 'transcribe', 'embed'] },
{ key: 'gemini', models_dev_id: 'google', keys_url: 'https://aistudio.google.com/apikey', display_name: 'Google AI Studio (Gemini API)', base_url: 'https://generativelanguage.googleapis.com/v1beta/openai',
{ key: 'gemini', models_dev_id: 'google', keys_url: 'https://aistudio.google.com/apikey', display_name: 'Google AI Studio (Gemini API)', base_url: 'https://generativelanguage.googleapis.com/v1beta/openai',
@@ -35,7 +35,7 @@ const DOMAIN = {
@@ -35,7 +35,7 @@ const DOMAIN = {
fireworks: 'fireworks.ai', groq: 'groq.com', cerebras: 'cerebras.ai', sambanova: 'sambanova.ai',
fireworks: 'fireworks.ai', groq: 'groq.com', cerebras: 'cerebras.ai', sambanova: 'sambanova.ai',
baseten: 'baseten.co', hyperbolic: 'hyperbolic.xyz', parasail: 'parasail.io', 'particle-ai': 'particle.ai',
baseten: 'baseten.co', hyperbolic: 'hyperbolic.xyz', parasail: 'parasail.io', 'particle-ai': 'particle.ai',
'inference-net': 'inference.net', 'atlas-cloud': 'atlascloud.ai', avian: 'avian.io',
'inference-net': 'inference.net', 'atlas-cloud': 'atlascloud.ai', avian: 'avian.io',
- nanogpt: 'nano-gpt.com', infermatic: 'totalgpt.ai', arliai: 'arliai.com', friendli: 'friendli.ai', scaleway: 'scaleway.com',
+ nanogpt: 'nano-gpt.com', infermatic: 'totalgpt.ai', arliai: 'arliai.com', friendli: 'friendli.ai', scaleway: 'scaleway.com', anthropic: 'claude.com',
iteracompute: 'iteracompute.com', sable: 'sableapi.com', inception: 'inceptionlabs.ai', dosai: 'dos.ai', 'runpod-vllm': 'runpod.io', meta: 'meta.ai',
iteracompute: 'iteracompute.com', sable: 'sableapi.com', inception: 'inceptionlabs.ai', dosai: 'dos.ai', 'runpod-vllm': 'runpod.io', meta: 'meta.ai',
};
};
const onItsOwnSite = (url, key) => {
const onItsOwnSite = (url, key) => {
new file mode 100644
new file mode 100644
@@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
+'use strict';
+const assert = require('node:assert/strict');
+const { boot, request, suite } = require('./helpers');
+const { byKey } = require('../server/providers/pool-providers');
+const { recordOf, modelOf } = require('../server/providers/pool-seed');
+
+const t = suite('anthropic-catalog');
+const anthropic = byKey.get('anthropic');
+const opus = anthropic.models.find((model) => model.model_key === 'claude-opus-5-5');
+let h;
+
+t.test('the Design model has an owner key slot and a sourced rate, but starts off', () => {
+ assert.equal(anthropic.default_model, opus.model_key);
+ assert.equal(recordOf(anthropic).status, 'disabled');
+ assert.equal(recordOf(anthropic).secret_ref, 'vault:anthropic');
+ assert.equal(recordOf(anthropic).provider_access, 'UNVERIFIED');
+ assert.deepEqual([modelOf(anthropic, opus).cost.in_per_mtok, modelOf(anthropic, opus).cost.out_per_mtok], [4, 20]);
+ assert.match(opus.source, /^https:\/\/platform\.claude\.com\/docs\/en\/models\/opus-5-5\//);
+});
+
+t.test('the model is seeded for owner configuration but a disabled provider is absent from public offers', async () => {
+ h = await boot();
+ assert.equal((await h.registry.getProvider('anthropic')).status, 'disabled');
+ assert.ok(await h.registry.getModel('anthropic', opus.model_key));
+ const r = await request(h.base, 'GET', '/api/v1/exchange/catalog');
+ assert.equal(r.status, 200);
+ assert.ok(!r.body.models.some((model) => model.canonical === 'anthropic/claude-opus-5-5'));
+});
+
+t.test('stop', async () => { if (h) await h.stop(); });
+t.run();