@opennodes/registry 0.1.1 → 0.1.2
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/README.md +21 -21
- package/bin.js +25 -25
- package/package.json +49 -49
- package/src/importers.js +346 -346
- package/src/mcp.js +182 -182
- package/src/reimport.js +55 -55
- package/src/search.js +123 -118
- package/src/server.js +392 -391
- package/src/stageb.js +19 -8
- package/src/store-pg.js +127 -127
- package/src/store.js +126 -126
- package/src/web/index.html +1794 -1778
package/README.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# @opennodes/registry
|
|
2
|
-
|
|
3
|
-
The OpenNodes Protocol (ONP) reference registry — an open, federatable discovery service for AI inference nodes.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npx @opennodes/registry # web app + API on http://127.0.0.1:4300
|
|
7
|
-
ONP_DB=./registry.db npx @opennodes/registry # persistent SQLite + persistent signing key
|
|
8
|
-
ONP_DB=postgres://user:pass@host/db npx @opennodes/registry
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
What it does:
|
|
12
|
-
|
|
13
|
-
- **Registration with proof of resource** — namespace challenge (HTTP or DNS TXT), Stage A conformance probes, Stage B identity fingerprinting / context verification / capacity ramp, Stage C continuous liveness and blind probes. Trust tiers: `unverified → community → verified` (+ `disputed`, `suspended`). Claimed ≠ measured ≠ attested — always labeled, never blended.
|
|
14
|
-
- **Search and transparent ranking** (`/v0/offerings`, `sort=rank|price|ttft|tps`) with per-result `rank_explanation`; **enforceable estimates** (`POST /v0/estimate`) pinned to card revisions; the **advisor** (`POST /v0/recommend`).
|
|
15
|
-
- **Catalog importers** — OpenRouter, Hugging Face Inference Providers, models.dev, the Ollama library — so search is useful on day one, with imported listings labeled and claimable by their operators.
|
|
16
|
-
- **MCP surface** at `/mcp` and a signed **export feed** for federation.
|
|
17
|
-
- **Web app** at `/`: OpenRouter-style catalog with model and node pages, hardware and measured performance, playground, multi-model chat (compare / jury / pipeline / iterative), the advisor, and the Node Builder.
|
|
18
|
-
|
|
19
|
-
Environment: `PORT`, `ONP_DB`, `ONP_REGISTRY_KEY`, `ONP_ADMIN_TOKEN`, `ONP_ALLOW_PRIVATE=1` (dev only: permit localhost nodes), `ONP_STAGE_C=0`, `ONP_REIMPORT=1`.
|
|
20
|
-
|
|
21
|
-
Part of [OpenNodes](https://opennodes.io) · [specification](https://github.com/opennodes-io/opennodes/tree/main/spec) · Apache-2.0.
|
|
1
|
+
# @opennodes/registry
|
|
2
|
+
|
|
3
|
+
The OpenNodes Protocol (ONP) reference registry — an open, federatable discovery service for AI inference nodes.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx @opennodes/registry # web app + API on http://127.0.0.1:4300
|
|
7
|
+
ONP_DB=./registry.db npx @opennodes/registry # persistent SQLite + persistent signing key
|
|
8
|
+
ONP_DB=postgres://user:pass@host/db npx @opennodes/registry
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
What it does:
|
|
12
|
+
|
|
13
|
+
- **Registration with proof of resource** — namespace challenge (HTTP or DNS TXT), Stage A conformance probes, Stage B identity fingerprinting / context verification / capacity ramp, Stage C continuous liveness and blind probes. Trust tiers: `unverified → community → verified` (+ `disputed`, `suspended`). Claimed ≠ measured ≠ attested — always labeled, never blended.
|
|
14
|
+
- **Search and transparent ranking** (`/v0/offerings`, `sort=rank|price|ttft|tps`) with per-result `rank_explanation`; **enforceable estimates** (`POST /v0/estimate`) pinned to card revisions; the **advisor** (`POST /v0/recommend`).
|
|
15
|
+
- **Catalog importers** — OpenRouter, Hugging Face Inference Providers, models.dev, the Ollama library — so search is useful on day one, with imported listings labeled and claimable by their operators.
|
|
16
|
+
- **MCP surface** at `/mcp` and a signed **export feed** for federation.
|
|
17
|
+
- **Web app** at `/`: OpenRouter-style catalog with model and node pages, hardware and measured performance, playground, multi-model chat (compare / jury / pipeline / iterative), the advisor, and the Node Builder.
|
|
18
|
+
|
|
19
|
+
Environment: `PORT`, `ONP_DB`, `ONP_REGISTRY_KEY`, `ONP_ADMIN_TOKEN`, `ONP_ALLOW_PRIVATE=1` (dev only: permit localhost nodes), `ONP_STAGE_C=0`, `ONP_REIMPORT=1`.
|
|
20
|
+
|
|
21
|
+
Part of [OpenNodes](https://opennodes.io) · [specification](https://github.com/opennodes-io/opennodes/tree/main/spec) · Apache-2.0.
|
package/bin.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { startRegistry } from './src/server.js';
|
|
3
|
-
|
|
4
|
-
const dbPath = process.env.ONP_DB ?? ':memory:'; // sqlite path/:memory: or postgres:// URL
|
|
5
|
-
const persistent = dbPath !== ':memory:' && !dbPath.startsWith('postgres');
|
|
6
|
-
const registry = await startRegistry({
|
|
7
|
-
port: Number(process.env.PORT ?? 4300),
|
|
8
|
-
host: process.env.HOST ?? '127.0.0.1', // 0.0.0.0 inside containers / behind a reverse proxy
|
|
9
|
-
dbPath,
|
|
10
|
-
// Persistent signing identity: explicit path, or derived from a file db; pg deployments set ONP_REGISTRY_KEY.
|
|
11
|
-
keyPath: process.env.ONP_REGISTRY_KEY ?? (persistent ? `${dbPath}.key.pem` : (dbPath.startsWith('postgres') ? 'onp-registry-key.pem' : null)),
|
|
12
|
-
allowPrivateTargets: process.env.ONP_ALLOW_PRIVATE === '1', // dev only: permit localhost nodes
|
|
13
|
-
adminToken: process.env.ONP_ADMIN_TOKEN ?? null,
|
|
14
|
-
stageC: process.env.ONP_STAGE_C === '0' ? null : {
|
|
15
|
-
livenessIntervalMs: Number(process.env.ONP_LIVENESS_MS ?? 300_000),
|
|
16
|
-
blindIntervalMs: Number(process.env.ONP_BLIND_MS ?? 3_600_000),
|
|
17
|
-
},
|
|
18
|
-
reimport: process.env.ONP_REIMPORT === '1' ? {
|
|
19
|
-
intervalMs: Number(process.env.ONP_REIMPORT_MS ?? 6 * 3600 * 1000),
|
|
20
|
-
sources: (process.env.ONP_REIMPORT_SOURCES ?? 'openrouter,huggingface').split(','),
|
|
21
|
-
} : null,
|
|
22
|
-
});
|
|
23
|
-
if (process.env.ONP_ALLOW_PRIVATE === '1') console.log('WARNING: SSRF guard disabled (ONP_ALLOW_PRIVATE=1) — dev only');
|
|
24
|
-
console.log(`opennodes registry listening at ${registry.origin}`);
|
|
25
|
-
console.log(`health: ${registry.origin}/v0/health`);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { startRegistry } from './src/server.js';
|
|
3
|
+
|
|
4
|
+
const dbPath = process.env.ONP_DB ?? ':memory:'; // sqlite path/:memory: or postgres:// URL
|
|
5
|
+
const persistent = dbPath !== ':memory:' && !dbPath.startsWith('postgres');
|
|
6
|
+
const registry = await startRegistry({
|
|
7
|
+
port: Number(process.env.PORT ?? 4300),
|
|
8
|
+
host: process.env.HOST ?? '127.0.0.1', // 0.0.0.0 inside containers / behind a reverse proxy
|
|
9
|
+
dbPath,
|
|
10
|
+
// Persistent signing identity: explicit path, or derived from a file db; pg deployments set ONP_REGISTRY_KEY.
|
|
11
|
+
keyPath: process.env.ONP_REGISTRY_KEY ?? (persistent ? `${dbPath}.key.pem` : (dbPath.startsWith('postgres') ? 'onp-registry-key.pem' : null)),
|
|
12
|
+
allowPrivateTargets: process.env.ONP_ALLOW_PRIVATE === '1', // dev only: permit localhost nodes
|
|
13
|
+
adminToken: process.env.ONP_ADMIN_TOKEN ?? null,
|
|
14
|
+
stageC: process.env.ONP_STAGE_C === '0' ? null : {
|
|
15
|
+
livenessIntervalMs: Number(process.env.ONP_LIVENESS_MS ?? 300_000),
|
|
16
|
+
blindIntervalMs: Number(process.env.ONP_BLIND_MS ?? 3_600_000),
|
|
17
|
+
},
|
|
18
|
+
reimport: process.env.ONP_REIMPORT === '1' ? {
|
|
19
|
+
intervalMs: Number(process.env.ONP_REIMPORT_MS ?? 6 * 3600 * 1000),
|
|
20
|
+
sources: (process.env.ONP_REIMPORT_SOURCES ?? 'openrouter,huggingface').split(','),
|
|
21
|
+
} : null,
|
|
22
|
+
});
|
|
23
|
+
if (process.env.ONP_ALLOW_PRIVATE === '1') console.log('WARNING: SSRF guard disabled (ONP_ALLOW_PRIVATE=1) — dev only');
|
|
24
|
+
console.log(`opennodes registry listening at ${registry.origin}`);
|
|
25
|
+
console.log(`health: ${registry.origin}/v0/health`);
|
package/package.json
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@opennodes/registry",
|
|
3
|
-
"version": "0.1.
|
|
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
|
-
"license": "Apache-2.0",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "src/server.js",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": "./src/server.js",
|
|
10
|
-
"./src/*": "./src/*"
|
|
11
|
-
},
|
|
12
|
-
"bin": {
|
|
13
|
-
"onp-registry": "bin.js"
|
|
14
|
-
},
|
|
15
|
-
"files": [
|
|
16
|
-
"bin.js",
|
|
17
|
-
"src",
|
|
18
|
-
"README.md"
|
|
19
|
-
],
|
|
20
|
-
"keywords": [
|
|
21
|
-
"opennodes",
|
|
22
|
-
"onp",
|
|
23
|
-
"registry",
|
|
24
|
-
"ai",
|
|
25
|
-
"inference",
|
|
26
|
-
"discovery",
|
|
27
|
-
"mcp",
|
|
28
|
-
"catalog"
|
|
29
|
-
],
|
|
30
|
-
"homepage": "https://opennodes.io",
|
|
31
|
-
"repository": {
|
|
32
|
-
"type": "git",
|
|
33
|
-
"url": "git+https://github.com/opennodes-io/opennodes.git",
|
|
34
|
-
"directory": "impl/packages/registry"
|
|
35
|
-
},
|
|
36
|
-
"bugs": {
|
|
37
|
-
"url": "https://github.com/opennodes-io/opennodes/issues"
|
|
38
|
-
},
|
|
39
|
-
"engines": {
|
|
40
|
-
"node": ">=22.5"
|
|
41
|
-
},
|
|
42
|
-
"publishConfig": {
|
|
43
|
-
"access": "public"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"@opennodes/core": "0.1.
|
|
47
|
-
"pg": "^8.13.1"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@opennodes/registry",
|
|
3
|
+
"version": "0.1.2",
|
|
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
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "src/server.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/server.js",
|
|
10
|
+
"./src/*": "./src/*"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"onp-registry": "bin.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin.js",
|
|
17
|
+
"src",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"opennodes",
|
|
22
|
+
"onp",
|
|
23
|
+
"registry",
|
|
24
|
+
"ai",
|
|
25
|
+
"inference",
|
|
26
|
+
"discovery",
|
|
27
|
+
"mcp",
|
|
28
|
+
"catalog"
|
|
29
|
+
],
|
|
30
|
+
"homepage": "https://opennodes.io",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/opennodes-io/opennodes.git",
|
|
34
|
+
"directory": "impl/packages/registry"
|
|
35
|
+
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/opennodes-io/opennodes/issues"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.5"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@opennodes/core": "0.1.1",
|
|
47
|
+
"pg": "^8.13.1"
|
|
48
|
+
}
|
|
49
|
+
}
|