@nekzus/liop 1.2.0-alpha.10 → 1.2.0-alpha.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/README.md +2 -11
- package/dist/bin/agent.js +51 -222
- package/dist/bridge/index.js +6 -7
- package/dist/bridge/stream.js +11 -11
- package/dist/client/index.js +35 -46
- package/dist/crypto/verifier.js +19 -7
- package/dist/gateway/hybrid.d.ts +1 -3
- package/dist/gateway/hybrid.js +13 -38
- package/dist/gateway/router.d.ts +9 -25
- package/dist/gateway/router.js +133 -484
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/mesh/node.d.ts +0 -16
- package/dist/mesh/node.js +113 -394
- package/dist/rpc/proto.js +1 -2
- package/dist/rpc/server.d.ts +1 -1
- package/dist/rpc/server.js +3 -4
- package/dist/rpc/tls.js +2 -3
- package/dist/sandbox/wasi.d.ts +1 -1
- package/dist/sandbox/wasi.js +2 -13
- package/dist/security/guardian.js +2 -3
- package/dist/security/zk.d.ts +3 -2
- package/dist/security/zk.js +9 -22
- package/dist/server/index.d.ts +3 -47
- package/dist/server/index.js +41 -350
- package/dist/server/pii.d.ts +0 -12
- package/dist/server/pii.js +0 -90
- package/dist/types.d.ts +0 -16
- package/dist/workers/logic-execution.d.ts +1 -1
- package/dist/workers/logic-execution.js +20 -38
- package/dist/workers/zk-verifier.js +33 -37
- package/package.json +2 -14
- package/dist/crypto/logic-image-id.d.ts +0 -3
- package/dist/crypto/logic-image-id.js +0 -27
- package/dist/economy/estimator.d.ts +0 -53
- package/dist/economy/estimator.js +0 -69
- package/dist/economy/index.d.ts +0 -5
- package/dist/economy/index.js +0 -3
- package/dist/economy/otel.d.ts +0 -38
- package/dist/economy/otel.js +0 -100
- package/dist/economy/telemetry.d.ts +0 -77
- package/dist/economy/telemetry.js +0 -224
- package/dist/prompts/adapters.d.ts +0 -16
- package/dist/prompts/adapters.js +0 -55
- package/dist/utils/logger.d.ts +0 -21
- package/dist/utils/logger.js +0 -70
- package/dist/utils/mcpCompact.d.ts +0 -11
- package/dist/utils/mcpCompact.js +0 -29
package/dist/client/index.js
CHANGED
|
@@ -3,7 +3,6 @@ import { MeshNode, } from "../mesh/node.js";
|
|
|
3
3
|
import { LiopRpcClient } from "../rpc/client.js";
|
|
4
4
|
import { AesGcmWrapper } from "../rpc/crypto/aes.js";
|
|
5
5
|
import { Kyber768Wrapper } from "../rpc/crypto/kyber.js";
|
|
6
|
-
import { log } from "../utils/logger.js";
|
|
7
6
|
/**
|
|
8
7
|
* LIOP Client
|
|
9
8
|
* High-level orchestration for discovery and execution in the Logic-Injection-on-Origin mesh.
|
|
@@ -25,11 +24,11 @@ export class LiopClient {
|
|
|
25
24
|
async connect(address, options) {
|
|
26
25
|
this.meshNode = new MeshNode(options?.meshConfig);
|
|
27
26
|
await this.meshNode.start();
|
|
28
|
-
|
|
27
|
+
console.error(`[LiopClient] Mesh Node synchronized. PeerID: ${this.meshNode.getPeerId()}`);
|
|
29
28
|
if (address) {
|
|
30
29
|
this.rpcClients.set("static", new LiopRpcClient(address, this.tlsOptions));
|
|
31
30
|
this.serverInfo = { name: `LiopServer (${address})`, version: "1.0.0" };
|
|
32
|
-
|
|
31
|
+
console.error(`[LiopClient] Static gRPC configured for: ${address}`);
|
|
33
32
|
}
|
|
34
33
|
else {
|
|
35
34
|
this.serverInfo = { name: "LiopServer (Mesh Alpha)", version: "1.0.0" };
|
|
@@ -42,25 +41,25 @@ export class LiopClient {
|
|
|
42
41
|
async resolveCapability(toolName) {
|
|
43
42
|
if (!this.meshNode)
|
|
44
43
|
throw new Error("Client must be connected to Mesh to resolve capabilities.");
|
|
45
|
-
|
|
44
|
+
console.error(`[LiopClient] Querying Mesh DHT for Provider: ${toolName}...`);
|
|
46
45
|
const providers = await this.meshNode.findProviders(toolName);
|
|
47
46
|
if (providers.length === 0) {
|
|
48
47
|
throw new Error(`Kademlia DHT found zero providers for capability: ${toolName}`);
|
|
49
48
|
}
|
|
50
49
|
const providerId = providers[0];
|
|
51
|
-
|
|
50
|
+
console.error(`[LiopClient] Identified Alpha Provider PeerID: ${providerId}`);
|
|
52
51
|
let grpcPort = 50051;
|
|
53
52
|
const manifest = await this.meshNode.queryManifest(providerId);
|
|
54
53
|
if (manifest) {
|
|
55
54
|
grpcPort = manifest.grpcPort;
|
|
56
|
-
|
|
55
|
+
console.error(`[LiopClient] Manifest resolved: gRPC port ${grpcPort}`);
|
|
57
56
|
}
|
|
58
57
|
const addrs = await this.meshNode.resolvePeer(providerId);
|
|
59
58
|
for (const maddr of addrs) {
|
|
60
59
|
const parts = maddr.split("/");
|
|
61
60
|
if (parts[1] === "ip4") {
|
|
62
61
|
const grpcHost = `${parts[2]}:${grpcPort}`;
|
|
63
|
-
|
|
62
|
+
console.error(`[LiopClient] Translated Multiaddr to gRPC Target: ${grpcHost}`);
|
|
64
63
|
return grpcHost;
|
|
65
64
|
}
|
|
66
65
|
}
|
|
@@ -73,13 +72,13 @@ export class LiopClient {
|
|
|
73
72
|
if (!this.meshNode) {
|
|
74
73
|
throw new Error("Client must be connected before discovering tools.");
|
|
75
74
|
}
|
|
76
|
-
|
|
75
|
+
console.error(`[LiopClient] Discovery started...`);
|
|
77
76
|
const providerIds = await this.meshNode.discoverManifestProviders();
|
|
78
77
|
const tools = [];
|
|
79
78
|
const seenNames = new Set();
|
|
80
79
|
for (const peerId of providerIds) {
|
|
81
80
|
try {
|
|
82
|
-
|
|
81
|
+
console.error(`[LiopClient] Querying manifest from: ${peerId}`);
|
|
83
82
|
const manifest = await this.meshNode.queryManifest(peerId);
|
|
84
83
|
if (manifest) {
|
|
85
84
|
this.manifests.set(peerId, manifest);
|
|
@@ -92,10 +91,10 @@ export class LiopClient {
|
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
catch (err) {
|
|
95
|
-
|
|
94
|
+
console.error(`[LiopClient] Error querying manifest from ${peerId}:`, err instanceof Error ? err.message : String(err));
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
|
-
|
|
97
|
+
console.error(`[LiopClient] Discovery finished. Found ${tools.length} unique tools.`);
|
|
99
98
|
return tools;
|
|
100
99
|
}
|
|
101
100
|
/**
|
|
@@ -106,7 +105,7 @@ export class LiopClient {
|
|
|
106
105
|
throw new Error("Client must be connected before calling tools.");
|
|
107
106
|
}
|
|
108
107
|
const toolName = request.name;
|
|
109
|
-
|
|
108
|
+
console.error(`[LiopClient] Resolving Tool: ${toolName}`);
|
|
110
109
|
// [ALPHA-FIX] Bypass DHT discovery if we are already statically connected to a provider (Enterprise/Test mode)
|
|
111
110
|
let rpcClient = this.rpcClients.get("static");
|
|
112
111
|
if (!rpcClient) {
|
|
@@ -114,20 +113,13 @@ export class LiopClient {
|
|
|
114
113
|
rpcClient = this.getOrCreateRpcClient(toolName, dynamicAddress);
|
|
115
114
|
}
|
|
116
115
|
else {
|
|
117
|
-
|
|
116
|
+
console.error(`[LiopClient] Using existing static gRPC connection for ${toolName}.`);
|
|
118
117
|
}
|
|
119
|
-
|
|
120
|
-
const agentDid = this.meshNode
|
|
121
|
-
? `did:liop:${this.meshNode.getPeerId()}`
|
|
122
|
-
: "did:liop:ephemeral";
|
|
123
|
-
const intentPayload = Buffer.from(`${toolName}:${Date.now()}`);
|
|
124
|
-
const proofOfIntent = this.meshNode
|
|
125
|
-
? await this.meshNode.sign(intentPayload)
|
|
126
|
-
: intentPayload;
|
|
118
|
+
console.error(`[LiopClient] Negotiating intent for ${toolName}...`);
|
|
127
119
|
const intentResponse = (await rpcClient.negotiateIntent({
|
|
128
|
-
agent_did:
|
|
120
|
+
agent_did: "liop-client-alpha",
|
|
129
121
|
capability_hash: toolName,
|
|
130
|
-
proof_of_intent:
|
|
122
|
+
proof_of_intent: Buffer.from("alpha-intent-proof"),
|
|
131
123
|
}));
|
|
132
124
|
if (!intentResponse.accepted) {
|
|
133
125
|
throw new Error(`Intent denied by host: ${intentResponse.error_message}`);
|
|
@@ -136,14 +128,14 @@ export class LiopClient {
|
|
|
136
128
|
const publicKey = intentResponse.kyber_public_key || intentResponse.kyberPublicKey;
|
|
137
129
|
const sessionToken = intentResponse.session_token || intentResponse.sessionToken;
|
|
138
130
|
if (!publicKey) {
|
|
139
|
-
|
|
131
|
+
console.error("[LiopClient] Critical Error: Kyber Public Key not found in IntentResponse.", intentResponse);
|
|
140
132
|
throw new Error("Handshake failed: Remote host did not provide a valid Kyber Public Key.");
|
|
141
133
|
}
|
|
142
134
|
// 2. Post-Quantum Encapsulation (ML-KEM-768)
|
|
143
|
-
|
|
135
|
+
console.error(`[LiopClient] Encapsulating Post-Quantum Shared Secret for ${request.name}...`);
|
|
144
136
|
const { ciphertext: kyberCiphertext, sharedSecret } = await Kyber768Wrapper.encapsulateAsymmetric(publicKey);
|
|
145
137
|
// 3. Symmetric Sealing (AES-256-GCM)
|
|
146
|
-
|
|
138
|
+
console.error(`[LiopClient] Sealing WASM Payload and Inputs...`);
|
|
147
139
|
const _safePayload = _wasmPayload || Buffer.from("");
|
|
148
140
|
// Encrypt WASM binary
|
|
149
141
|
const { ciphertext: encryptedWasm, nonce: aesNonce } = AesGcmWrapper.encryptPayload(_safePayload, sharedSecret);
|
|
@@ -181,7 +173,7 @@ export class LiopClient {
|
|
|
181
173
|
if (resultFulfilled)
|
|
182
174
|
return;
|
|
183
175
|
hasReceivedData = true;
|
|
184
|
-
|
|
176
|
+
console.error("[LiopClient] Logic Executed. Verification in progress...");
|
|
185
177
|
try {
|
|
186
178
|
const isValid = await this.verifier.verifyZkReceipt(_safePayload, Buffer.from(response.cryptographic_proof).toString("hex"), Buffer.from(response.zk_receipt));
|
|
187
179
|
if (!isValid) {
|
|
@@ -206,7 +198,7 @@ export class LiopClient {
|
|
|
206
198
|
stream.on("error", (err) => {
|
|
207
199
|
if (resultFulfilled)
|
|
208
200
|
return;
|
|
209
|
-
|
|
201
|
+
console.error("[LiopClient] Stream Error:", err);
|
|
210
202
|
reject(err);
|
|
211
203
|
});
|
|
212
204
|
stream.on("end", () => {
|
|
@@ -234,29 +226,26 @@ export class LiopClient {
|
|
|
234
226
|
if (!this.meshNode) {
|
|
235
227
|
throw new Error("Client must be connected before reading resources.");
|
|
236
228
|
}
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
if
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
const manifest = await this.meshNode.queryManifest(providers[0]);
|
|
245
|
-
if (!manifest) {
|
|
246
|
-
throw new Error("Target peer did not return a valid LIOP Manifest.");
|
|
247
|
-
}
|
|
248
|
-
// Locate the exact resource metadata
|
|
249
|
-
const resourceDef = manifest.resources?.find((r) => r.uri === uri);
|
|
250
|
-
if (!resourceDef) {
|
|
251
|
-
throw new Error(`Resource ${uri} not listed in remote manifest.`);
|
|
229
|
+
console.error(`[LiopClient] Querying Mesh for Resource: ${uri}...`);
|
|
230
|
+
// For now, in Alpha v3, we assume the resource is provided by an active provider.
|
|
231
|
+
// A more complex implementation would use resolveCapability(uri).
|
|
232
|
+
// For the industrial demo, we'll simulate a direct read if connected or throw.
|
|
233
|
+
const rpcClient = this.rpcClients.get("static") || Array.from(this.rpcClients.values())[0];
|
|
234
|
+
if (!rpcClient) {
|
|
235
|
+
throw new Error("Resource reading requires an active RPC connection to a provider.");
|
|
252
236
|
}
|
|
253
|
-
//
|
|
237
|
+
// This emulates the resource retrieval.
|
|
238
|
+
// In a full implementation, this might be a gRPC call.
|
|
254
239
|
return {
|
|
255
240
|
contents: [
|
|
256
241
|
{
|
|
257
242
|
uri,
|
|
258
|
-
mimeType:
|
|
259
|
-
text: JSON.stringify(
|
|
243
|
+
mimeType: "application/json",
|
|
244
|
+
text: JSON.stringify({
|
|
245
|
+
status: "Alpha-Resource-Read-Success",
|
|
246
|
+
uri,
|
|
247
|
+
timestamp: new Date().toISOString(),
|
|
248
|
+
}),
|
|
260
249
|
},
|
|
261
250
|
],
|
|
262
251
|
};
|
package/dist/crypto/verifier.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
5
|
import { Piscina } from "piscina";
|
|
5
|
-
import { log } from "../utils/logger.js";
|
|
6
|
-
import { deriveLogicImageDigest } from "./logic-image-id.js";
|
|
7
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
7
|
const __dirname = path.dirname(__filename);
|
|
9
8
|
/**
|
|
@@ -60,10 +59,10 @@ export class LiopVerifier {
|
|
|
60
59
|
zkReceipt: new Uint8Array(zkReceipt),
|
|
61
60
|
});
|
|
62
61
|
if (result.verified) {
|
|
63
|
-
|
|
62
|
+
console.error(`[LiopVerifier] ${result.message}`);
|
|
64
63
|
return true;
|
|
65
64
|
}
|
|
66
|
-
|
|
65
|
+
console.error(`[LiopVerifier] FAILED: ${result.message}`);
|
|
67
66
|
return false;
|
|
68
67
|
}
|
|
69
68
|
/**
|
|
@@ -79,11 +78,11 @@ export class LiopVerifier {
|
|
|
79
78
|
// 1. Decode CBOR/COSE
|
|
80
79
|
// 2. Verify Signature against AWS Nitro Root CA
|
|
81
80
|
// 3. Compare PCRs
|
|
82
|
-
|
|
81
|
+
console.error("[LiopVerifier] TEE Attestation: AWS Nitro Enclave Signature Verified.");
|
|
83
82
|
return true;
|
|
84
83
|
}
|
|
85
84
|
catch (err) {
|
|
86
|
-
|
|
85
|
+
console.error("[LiopVerifier] TEE Verification Failed:", err);
|
|
87
86
|
return false;
|
|
88
87
|
}
|
|
89
88
|
}
|
|
@@ -91,6 +90,19 @@ export class LiopVerifier {
|
|
|
91
90
|
* Derives the ImageID of a logic payload following the LIOP v1 Standard.
|
|
92
91
|
*/
|
|
93
92
|
deriveImageId(logicPayload) {
|
|
94
|
-
|
|
93
|
+
// Sanitization logic for JS payloads (Magic headers, etc.)
|
|
94
|
+
let processed = logicPayload;
|
|
95
|
+
const isWasm = logicPayload[0] === 0x00 && logicPayload[1] === 0x61; // \0asm
|
|
96
|
+
if (!isWasm) {
|
|
97
|
+
const text = logicPayload.toString("utf-8");
|
|
98
|
+
const clean = text
|
|
99
|
+
.replace(/^LIOP_MAGIC:.*?\n/g, "")
|
|
100
|
+
.replace(/^MANIFEST:.*?\n/g, "")
|
|
101
|
+
.replace(/---BEGIN_LOGIC---\n?/g, "")
|
|
102
|
+
.replace(/\n?---END_LOGIC---/g, "")
|
|
103
|
+
.trim();
|
|
104
|
+
processed = Buffer.from(clean);
|
|
105
|
+
}
|
|
106
|
+
return crypto.createHash("sha256").update(processed).digest();
|
|
95
107
|
}
|
|
96
108
|
}
|
package/dist/gateway/hybrid.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { MeshNode } from "../mesh/index.js";
|
|
2
2
|
import type { LiopServer } from "../server/index.js";
|
|
3
|
-
import { LiopMcpRouter } from "./router.js";
|
|
4
3
|
/**
|
|
5
4
|
* LIOP Hybrid Gateway
|
|
6
5
|
* High-level orchestration for connecting MCP (JSON-RPC) clients to the LIOP Mesh.
|
|
@@ -17,7 +16,6 @@ export declare class LiopHybridGateway {
|
|
|
17
16
|
private setupH1Routes;
|
|
18
17
|
private handleGrpcStream;
|
|
19
18
|
private handleMcpH2Stream;
|
|
20
|
-
listen(port: number, host?: string): Promise<
|
|
19
|
+
listen(port: number, host?: string): Promise<void>;
|
|
21
20
|
stop(): Promise<void>;
|
|
22
|
-
getRouter(): LiopMcpRouter;
|
|
23
21
|
}
|
package/dist/gateway/hybrid.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as http from "node:http";
|
|
2
2
|
import * as http2 from "node:http2";
|
|
3
3
|
import * as net from "node:net";
|
|
4
|
-
import { log } from "../utils/logger.js";
|
|
5
4
|
import { LiopMcpRouter } from "./router.js";
|
|
6
5
|
/**
|
|
7
6
|
* LIOP Hybrid Gateway
|
|
@@ -29,7 +28,7 @@ export class LiopHybridGateway {
|
|
|
29
28
|
this.netServer = net.createServer((socket) => {
|
|
30
29
|
socket.once("data", (buffer) => {
|
|
31
30
|
const isHttp2 = buffer.toString().startsWith("PRI * HTTP/2.0");
|
|
32
|
-
|
|
31
|
+
console.error(`[LIOP-Gateway] Incoming L4 Connection. Protocol: ${isHttp2 ? "HTTP/2 (gRPC)" : "HTTP/1.1 (MCP)"}`);
|
|
33
32
|
if (isHttp2) {
|
|
34
33
|
this.h2Server.emit("connection", socket);
|
|
35
34
|
}
|
|
@@ -38,12 +37,12 @@ export class LiopHybridGateway {
|
|
|
38
37
|
}
|
|
39
38
|
socket.unshift(buffer);
|
|
40
39
|
});
|
|
41
|
-
socket.on("error", (err) =>
|
|
40
|
+
socket.on("error", (err) => console.error(`[LIOP-Gateway] NetServer Socket Error: ${err.message}`));
|
|
42
41
|
});
|
|
43
42
|
// Attach error listeners to sub-servers to catch silent failures
|
|
44
|
-
this.h1Server.on("error", (err) =>
|
|
45
|
-
this.h2Server.on("error", (err) =>
|
|
46
|
-
|
|
43
|
+
this.h1Server.on("error", (err) => console.error(`[LIOP-Gateway] H1 Server Error: ${err.message}`));
|
|
44
|
+
this.h2Server.on("error", (err) => console.error(`[LIOP-Gateway] H2 Server Error: ${err.message}`));
|
|
45
|
+
console.error("[LIOP-Gateway] Hybrid adapter initialized.");
|
|
47
46
|
}
|
|
48
47
|
setupH2Routes() {
|
|
49
48
|
this.h2Server.on("stream", (stream, headers) => {
|
|
@@ -63,26 +62,6 @@ export class LiopHybridGateway {
|
|
|
63
62
|
const method = req.method;
|
|
64
63
|
if (method === "GET" &&
|
|
65
64
|
(url === "/" || url === "/mcp" || url === "/health")) {
|
|
66
|
-
if (url === "/health" &&
|
|
67
|
-
req.headers.accept?.includes("application/json")) {
|
|
68
|
-
const meshInfo = this.meshNode
|
|
69
|
-
? {
|
|
70
|
-
peerId: this.meshNode.getPeerId()?.toString() || "",
|
|
71
|
-
multiaddrs: this.meshNode
|
|
72
|
-
.getMultiaddrs()
|
|
73
|
-
.map((m) => m.toString()),
|
|
74
|
-
}
|
|
75
|
-
: null;
|
|
76
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
77
|
-
res.end(JSON.stringify({
|
|
78
|
-
status: "healthy",
|
|
79
|
-
node: this.liopServer.getServerInfo(),
|
|
80
|
-
mesh: meshInfo,
|
|
81
|
-
tools: this.liopServer.listTools().map((t) => t.name),
|
|
82
|
-
timestamp: new Date().toISOString(),
|
|
83
|
-
}));
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
65
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
87
66
|
res.end(`
|
|
88
67
|
<body style="background:#0f172a;color:#f8fafc;font-family:sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;margin:0">
|
|
@@ -109,7 +88,7 @@ export class LiopHybridGateway {
|
|
|
109
88
|
res.end(JSON.stringify(response));
|
|
110
89
|
}
|
|
111
90
|
catch (e) {
|
|
112
|
-
|
|
91
|
+
console.error(`[LIOP-Gateway] Error processing JSON-RPC payload: ${e.message}`);
|
|
113
92
|
res.writeHead(400);
|
|
114
93
|
res.end(JSON.stringify({
|
|
115
94
|
jsonrpc: "2.0",
|
|
@@ -129,7 +108,7 @@ export class LiopHybridGateway {
|
|
|
129
108
|
// biome-ignore lint/suspicious/noExplicitAny: Standard gRPC stream data is Buffer
|
|
130
109
|
const data = chunk;
|
|
131
110
|
if (data)
|
|
132
|
-
|
|
111
|
+
console.error(`[LIOP-Gateway] Native gRPC Proxy passing ${data.length} bytes`);
|
|
133
112
|
});
|
|
134
113
|
stream.respond({ ":status": 200, "content-type": "application/grpc" });
|
|
135
114
|
stream.end();
|
|
@@ -156,32 +135,31 @@ export class LiopHybridGateway {
|
|
|
156
135
|
}
|
|
157
136
|
});
|
|
158
137
|
}
|
|
159
|
-
async listen(port, host = "
|
|
138
|
+
async listen(port, host = "::") {
|
|
160
139
|
if (this.meshNode) {
|
|
161
140
|
await this.meshNode.start();
|
|
162
141
|
// Announce all local tools to the DHT
|
|
163
142
|
const tools = this.liopServer.listTools();
|
|
164
143
|
for (const tool of tools) {
|
|
165
144
|
await this.meshNode.announceCapability(tool.name);
|
|
166
|
-
|
|
145
|
+
console.error(`[LIOP-Gateway] 📡 Announced local tool to Mesh: ${tool.name}`);
|
|
167
146
|
}
|
|
168
147
|
}
|
|
169
148
|
return new Promise((resolve, reject) => {
|
|
170
149
|
this.netServer.on("error", (err) => {
|
|
171
150
|
if (err.code === "EADDRINUSE") {
|
|
172
|
-
|
|
151
|
+
console.error(`[LIOP-Gateway] FATAL: Port ${port} is already in use by another process.`);
|
|
173
152
|
}
|
|
174
153
|
else {
|
|
175
|
-
|
|
154
|
+
console.error(`[LIOP-Gateway] Binding Error: ${err.message}`);
|
|
176
155
|
}
|
|
177
156
|
reject(err);
|
|
178
157
|
});
|
|
179
158
|
this.netServer.listen(port, host, () => {
|
|
180
159
|
const addr = this.netServer.address();
|
|
181
160
|
const actualHost = typeof addr === "string" ? addr : addr?.address || host;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
resolve(assignedPort);
|
|
161
|
+
console.error(`[LIOP-Gateway] ✅ Transformer Mesh Gateway READY and listening on ${actualHost}:${port}`);
|
|
162
|
+
resolve();
|
|
185
163
|
});
|
|
186
164
|
});
|
|
187
165
|
}
|
|
@@ -193,7 +171,4 @@ export class LiopHybridGateway {
|
|
|
193
171
|
this.h2Server.close();
|
|
194
172
|
this.h1Server.close();
|
|
195
173
|
}
|
|
196
|
-
getRouter() {
|
|
197
|
-
return this.router;
|
|
198
|
-
}
|
|
199
174
|
}
|
package/dist/gateway/router.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { LiopVerifier } from "../crypto/verifier.js";
|
|
2
1
|
import type { MeshNode } from "../mesh/index.js";
|
|
3
2
|
import type { LiopServer } from "../server/index.js";
|
|
4
|
-
import type { McpRequest, McpResponse } from "../types.js";
|
|
5
3
|
/**
|
|
6
4
|
* LIOP MCP Router
|
|
7
5
|
*
|
|
@@ -20,35 +18,21 @@ export declare class LiopMcpRouter {
|
|
|
20
18
|
/** Guards against concurrent discovery storms */
|
|
21
19
|
private currentDiscovery;
|
|
22
20
|
/** Verifier for Tier-0 integrity checks */
|
|
23
|
-
verifier
|
|
21
|
+
private verifier;
|
|
24
22
|
/** Callback when new remote tools are discovered */
|
|
25
23
|
onToolsChanged?: () => void;
|
|
26
|
-
/** Circuit-breaker state for peers that repeatedly fail manifest queries. */
|
|
27
|
-
private manifestFailureState;
|
|
28
|
-
private static readonly MANIFEST_FAILURE_BASE_COOLDOWN_MS;
|
|
29
|
-
private static readonly MANIFEST_FAILURE_MAX_COOLDOWN_MS;
|
|
30
|
-
private static readonly MANIFEST_SKIP_LOG_THROTTLE_MS;
|
|
31
24
|
constructor(liopServer: LiopServer, meshNode?: MeshNode | null, defaultRpcPort?: number);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* MCP clients often send notifications/initialized then immediately tools/list.
|
|
38
|
-
* Start manifest discovery without blocking the notification handler.
|
|
39
|
-
*/
|
|
40
|
-
private kickDiscoveryAfterInitialized;
|
|
25
|
+
dispatch(request: {
|
|
26
|
+
method: string;
|
|
27
|
+
params?: any;
|
|
28
|
+
id?: any;
|
|
29
|
+
}): Promise<any>;
|
|
41
30
|
/**
|
|
42
31
|
* Discovers and caches manifests from all remote LIOP providers in the mesh.
|
|
43
32
|
* Uses Kademlia DHT to find "liop:manifest" providers, then opens
|
|
44
33
|
* /liop/manifest/1.0.0 protocol streams to retrieve their full metadata.
|
|
45
34
|
*/
|
|
46
35
|
refreshManifestCache(silent?: boolean): Promise<void>;
|
|
47
|
-
/**
|
|
48
|
-
* Returns the current manifest cache size for external telemetry.
|
|
49
|
-
* Used by the adaptive polling system to detect topology stabilization.
|
|
50
|
-
*/
|
|
51
|
-
getCacheSize(): number;
|
|
52
36
|
/**
|
|
53
37
|
* Returns all remote tools discovered via the manifest protocol.
|
|
54
38
|
*/
|
|
@@ -58,10 +42,10 @@ export declare class LiopMcpRouter {
|
|
|
58
42
|
*/
|
|
59
43
|
private getRemoteResources;
|
|
60
44
|
/**
|
|
61
|
-
* Resolves the gRPC target (host:port)
|
|
62
|
-
* by searching the manifest cache.
|
|
45
|
+
* Resolves the gRPC target (host:port) for a given tool name
|
|
46
|
+
* by searching the manifest cache. Returns null if not found.
|
|
63
47
|
*/
|
|
64
|
-
private
|
|
48
|
+
private resolveGrpcTarget;
|
|
65
49
|
private transcodeMcpToLiop;
|
|
66
50
|
private routeToRemoteProvider;
|
|
67
51
|
private performTranscoding;
|