@opennodes/registry 0.1.18 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/importers.js +12 -1
- package/src/search.js +8 -2
- package/src/web/index.html +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennodes/registry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "OpenNodes (ONP) reference registry: node registration with proof-of-resource qualification (Stage A/B/C), transparent ranking, enforceable estimates, catalog importers (OpenRouter, Hugging Face, models.dev, Ollama), MCP surface, and the web app (catalog, chat, advisor, Node Builder)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@opennodes/core": "0.1.
|
|
46
|
+
"@opennodes/core": "0.1.4",
|
|
47
47
|
"pg": "^8.13.1"
|
|
48
48
|
}
|
|
49
49
|
}
|
package/src/importers.js
CHANGED
|
@@ -60,6 +60,17 @@ export const MODELS_DEV_API_BASES = {
|
|
|
60
60
|
openai: 'https://api.openai.com/v1',
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Country of providers whose own API we import directly and whose company and inference hosting
|
|
65
|
+
* are known to be in that country — conservative on purpose (routers, gateways and providers with
|
|
66
|
+
* mixed or unclear hosting are left out). Imports carry it as an *inferred* jurisdiction; only the
|
|
67
|
+
* operator's own signed card can declare one.
|
|
68
|
+
*/
|
|
69
|
+
export const KNOWN_PROVIDER_COUNTRY = Object.freeze({
|
|
70
|
+
'cloudferro-sherlock': 'PL', berget: 'SE', evroc: 'SE', 'regolo-ai': 'IT', scaleway: 'FR', ovhcloud: 'FR',
|
|
71
|
+
mistral: 'FR', stackit: 'DE', hetzner: 'DE', infomaniak: 'CH',
|
|
72
|
+
});
|
|
73
|
+
|
|
63
74
|
/**
|
|
64
75
|
* Import a models.dev-shaped catalog: { providerId: { id, name, api?, doc?, models: { key: model } } }.
|
|
65
76
|
* Each provider becomes a synthetic node `import.modelsdev.{provider}`; each model an offering.
|
|
@@ -111,7 +122,7 @@ export async function importModelsDev(store, catalog) {
|
|
|
111
122
|
id: nodeId,
|
|
112
123
|
name: provider?.name ?? providerId,
|
|
113
124
|
description: `Imported from models.dev; metadata only, unclaimed by the operator.`,
|
|
114
|
-
operator: { name: provider?.name ?? providerId },
|
|
125
|
+
operator: { name: provider?.name ?? providerId, ...(KNOWN_PROVIDER_COUNTRY[providerId] ? { country: KNOWN_PROVIDER_COUNTRY[providerId] } : {}) },
|
|
115
126
|
},
|
|
116
127
|
endpoints: {
|
|
117
128
|
...(base ? { openai: base, health: `${base}/health` } : {}),
|
package/src/search.js
CHANGED
|
@@ -40,8 +40,14 @@ export async function collectOfferings(store) {
|
|
|
40
40
|
binding: offering.binding,
|
|
41
41
|
pricing: offering.pricing,
|
|
42
42
|
data_policy: offering.data_policy ?? null,
|
|
43
|
-
// Where the operator
|
|
44
|
-
|
|
43
|
+
// Where the operator is (ONP-2 node.operator.country, node.regions).
|
|
44
|
+
// Registered nodes declare it in their signed card; imports get it from the importer's list of
|
|
45
|
+
// known providers, labeled inferred.
|
|
46
|
+
jurisdiction: {
|
|
47
|
+
country: card.node?.operator?.country ?? null,
|
|
48
|
+
regions: card.node?.regions ?? [],
|
|
49
|
+
basis: card.node?.operator?.country ? (node.source === 'import' ? 'inferred' : 'declared') : null,
|
|
50
|
+
},
|
|
45
51
|
// Allocated hardware for THIS offering (offering-level override wins over the
|
|
46
52
|
// node-level description) — same artifact on different vendors runs on different
|
|
47
53
|
// silicon, and clients deserve to see which. Always basis-labeled, never measured.
|
package/src/web/index.html
CHANGED
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
<div class="toolbar">
|
|
220
220
|
<input type="text" id="f-q" placeholder="Search models, families, nodes…">
|
|
221
221
|
<span class="switchrow" id="f-verified" title="identity-fingerprinted · context-verified · continuously probed"><span class="switch"></span><b style="font-size:0.78rem">Verified only</b></span>
|
|
222
|
-
<span class="switchrow" id="f-eea" title="operators
|
|
222
|
+
<span class="switchrow" id="f-eea" title="operators in the EU, Iceland, Liechtenstein or Norway — declared by registered nodes, inferred for imported listings of known European providers"><span class="switch"></span><b style="font-size:0.78rem">EU/EEA</b></span>
|
|
223
223
|
<select id="f-modality">
|
|
224
224
|
<option value="">any modality</option>
|
|
225
225
|
<option>text</option><option>multimodal</option><option>image</option>
|
|
@@ -1805,7 +1805,7 @@ async function loadNode(id) {
|
|
|
1805
1805
|
<div class="statstrip">
|
|
1806
1806
|
${stat(tierChip(tier), 'TRUST TIER')}
|
|
1807
1807
|
${stat(String(offers.length), 'OFFERINGS')}
|
|
1808
|
-
${card.node?.operator?.name ? stat(esc(card.node.operator.name) + (card.node.operator.country ? ' (' + esc(card.node.operator.country) + ')' : ''), 'OPERATOR') : ''}
|
|
1808
|
+
${card.node?.operator?.name ? stat(esc(card.node.operator.name) + (card.node.operator.country ? ' (' + esc(card.node.operator.country) + (n.source === 'import' ? ' · inferred' : '') + ')' : ''), 'OPERATOR') : ''}
|
|
1809
1809
|
${(card.node?.regions || []).length ? stat(esc(card.node.regions.join(', ')), 'REGIONS') : ''}
|
|
1810
1810
|
${n.source === 'import' ? stat('<span class="chip imp">IMPORTED</span>', 'SOURCE — unclaimed by operator') : ''}
|
|
1811
1811
|
</div>
|