@opennodes/registry 0.1.7 → 0.1.9
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/stagec.js +25 -1
- package/src/web/index.html +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennodes/registry",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
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/stagec.js
CHANGED
|
@@ -13,12 +13,27 @@ export function startStageC(store, {
|
|
|
13
13
|
livenessIntervalMs = 300_000, // spec: <=5 min; tests shorten this
|
|
14
14
|
blindIntervalMs = 3_600_000,
|
|
15
15
|
failThreshold = 3,
|
|
16
|
+
recoverThreshold = 3, // consecutive liveness successes that lift a liveness suspension
|
|
16
17
|
} = {}) {
|
|
17
18
|
let stopped = false;
|
|
18
19
|
|
|
20
|
+
/**
|
|
21
|
+
* A suspension for liveness is temporary: the node is still probed, and after
|
|
22
|
+
* `recoverThreshold` consecutive successes it returns to the tier it held. Suspensions
|
|
23
|
+
* for any other reason (dispute, fraud, operator request) are never lifted here.
|
|
24
|
+
* Returns the tier to restore to, or null when the node is not eligible.
|
|
25
|
+
*/
|
|
26
|
+
async function livenessSuspension(node) {
|
|
27
|
+
if (node.state !== 'suspended') return null;
|
|
28
|
+
const last = [...(await store.transitionsFor(node.id))].reverse().find((t) => t.to_state === 'suspended');
|
|
29
|
+
if (!last || !String(last.reason ?? '').startsWith('liveness:')) return null;
|
|
30
|
+
return OBSERVED_STATES.includes(last.from_state) ? last.from_state : 'community';
|
|
31
|
+
}
|
|
32
|
+
|
|
19
33
|
async function livenessSweep() {
|
|
20
34
|
for (const node of await store.allNodes()) {
|
|
21
|
-
|
|
35
|
+
const restoreTo = await livenessSuspension(node);
|
|
36
|
+
if (!OBSERVED_STATES.includes(node.state) && !restoreTo) continue;
|
|
22
37
|
const card = await store.latestCard(node.id);
|
|
23
38
|
if (!card) continue;
|
|
24
39
|
let ok = false;
|
|
@@ -37,6 +52,15 @@ export function startStageC(store, {
|
|
|
37
52
|
ratio: recent.length ? Math.round((up / recent.length) * 1000) / 1000 : null,
|
|
38
53
|
});
|
|
39
54
|
|
|
55
|
+
if (restoreTo) {
|
|
56
|
+
let consecutiveOk = 0;
|
|
57
|
+
for (const p of recent) { if (!p.ok) break; consecutiveOk++; }
|
|
58
|
+
if (consecutiveOk >= recoverThreshold) {
|
|
59
|
+
await store.setState(node.id, restoreTo, `reinstated: ${consecutiveOk} consecutive liveness successes`);
|
|
60
|
+
await refreshCard?.(node.id); // it may have restarted with a new card revision
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
40
64
|
let consecutiveFails = 0;
|
|
41
65
|
for (const p of recent) { if (p.ok) break; consecutiveFails++; }
|
|
42
66
|
if (consecutiveFails >= failThreshold) {
|
package/src/web/index.html
CHANGED
|
@@ -414,7 +414,7 @@
|
|
|
414
414
|
</div>
|
|
415
415
|
<div class="panel pad">
|
|
416
416
|
<span class="lab" style="font-family:'IBM Plex Mono',monospace; font-size:0.62rem; font-weight:600; letter-spacing:0.12em; color:var(--accent)">DESKTOP & APPS</span>
|
|
417
|
-
<p style="font-size:0.8rem; color:var(--muted); margin:0.5rem 0 0.4rem"><b>Surge</b>, a desktop client with native OpenNodes support (models + MCP tools in one app), is in pre-release:
|
|
417
|
+
<p style="font-size:0.8rem; color:var(--muted); margin:0.5rem 0 0.4rem"><b>Surge</b>, a desktop client with native OpenNodes support (models + MCP tools in one app), is in pre-release: <a href="https://github.com/opennodes-io/surge/releases">download the Windows installer</a>, or get the <a href="https://github.com/opennodes-io/surge">source on GitHub</a>.</p>
|
|
418
418
|
<p style="font-size:0.8rem; color:var(--muted); margin:0">Available today: bring every model here into <b>Cursor, VS Code, or any OpenAI-compatible app</b> via the <a href="https://github.com/opennodes-io/opennodes/tree/main/impl">onp gateway and MCP server</a>.</p>
|
|
419
419
|
</div>
|
|
420
420
|
</div>
|