@opennodes/registry 0.1.16 → 0.1.17
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 +1 -1
- package/src/web/index.html +31 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennodes/registry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
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",
|
package/src/web/index.html
CHANGED
|
@@ -1743,6 +1743,36 @@ async function loadFeed() {
|
|
|
1743
1743
|
}
|
|
1744
1744
|
|
|
1745
1745
|
/* ---------- node detail ---------- */
|
|
1746
|
+
/**
|
|
1747
|
+
* Imported listings invite their operator to claim them (ONP-3 §4: a registered node whose
|
|
1748
|
+
* namespace covers the import's API host supersedes it). Providers reached through the HF router
|
|
1749
|
+
* can't claim via huggingface.co, so they are invited to list their own API instead.
|
|
1750
|
+
*/
|
|
1751
|
+
const CLAIM_GUIDE = 'https://github.com/opennodes-io/opennodes/tree/main/node-kit#card-only-listing-you-already-run-an-openai-compatible-api';
|
|
1752
|
+
function claimBanner(n, card) {
|
|
1753
|
+
if (n.source !== 'import' || ['delisted', 'claimed'].includes(n.state)) return '';
|
|
1754
|
+
const name = card.node?.operator?.name || card.node?.name || n.id;
|
|
1755
|
+
let host = null;
|
|
1756
|
+
try { host = new URL(card.endpoints?.openai).hostname; } catch { /* listing without an API */ }
|
|
1757
|
+
const viaHf = host === 'router.huggingface.co';
|
|
1758
|
+
const suggestedId = host && !viaHf ? host.split('.').reverse().join('.') : null;
|
|
1759
|
+
const body = viaHf
|
|
1760
|
+
? `This listing reaches <b>${esc(name)}</b> through the Hugging Face router, so it is shown as an unprobed catalog import. List your own API directly to have it measured and verified by this registry.`
|
|
1761
|
+
: host
|
|
1762
|
+
? `Claim it: publish a signed Node Card at <span class="mono">https://${esc(host)}/.well-known/open-node.json</span> with node id <span class="mono">${esc(suggestedId)}</span> (your parent domain works too) and register. Your verified listing replaces this import, the registry measures what you really serve, and nothing in your stack changes.`
|
|
1763
|
+
: 'This listing has no known API endpoint. Publish a Node Card for your OpenAI-compatible API to be listed, measured and verified.';
|
|
1764
|
+
const mail = `mailto:operators@opennodes.io?subject=${encodeURIComponent('Claim ' + n.id)}`;
|
|
1765
|
+
return `<div class="panel pad" style="max-width:56rem; margin:0.4rem 0 0.8rem; border-left:3px solid var(--accent)">
|
|
1766
|
+
<p style="margin:0 0 0.35rem; font-weight:600">Do you run ${esc(name)}?</p>
|
|
1767
|
+
<p style="margin:0 0 0.6rem; font-size:0.86rem; color:var(--muted); overflow-wrap:anywhere">${body} Free, about 15 minutes with the Node Kit.</p>
|
|
1768
|
+
<span style="display:inline-flex; gap:0.6rem; flex-wrap:wrap; font-size:0.84rem">
|
|
1769
|
+
<a href="${CLAIM_GUIDE}" target="_blank" rel="noopener">How to claim →</a>
|
|
1770
|
+
<a href="#/register">Register a node</a>
|
|
1771
|
+
<a href="${mail}">operators@opennodes.io</a>
|
|
1772
|
+
</span>
|
|
1773
|
+
</div>`;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1746
1776
|
async function loadNode(id) {
|
|
1747
1777
|
$('#node-title').textContent = id;
|
|
1748
1778
|
try {
|
|
@@ -1764,6 +1794,7 @@ async function loadNode(id) {
|
|
|
1764
1794
|
<td>${(o.serving?.supports || []).filter((s) => s !== 'streaming').map((s) => `<span class="chip">${esc(s)}</span>`).join(' ') || '—'}</td>
|
|
1765
1795
|
</tr>`).join('');
|
|
1766
1796
|
$('#node-detail').innerHTML = `
|
|
1797
|
+
${claimBanner(n, card)}
|
|
1767
1798
|
${card.node?.description ? `<p class="desc">${esc(card.node.description)}</p>` : ''}
|
|
1768
1799
|
<div class="statstrip">
|
|
1769
1800
|
${stat(tierChip(tier), 'TRUST TIER')}
|