@nekzus/liop 1.2.0-alpha.10
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/LICENSE +21 -0
- package/README.md +413 -0
- package/dist/bin/agent.d.ts +2 -0
- package/dist/bin/agent.js +307 -0
- package/dist/bridge/index.d.ts +37 -0
- package/dist/bridge/index.js +249 -0
- package/dist/bridge/stream.d.ts +62 -0
- package/dist/bridge/stream.js +202 -0
- package/dist/client/index.d.ts +60 -0
- package/dist/client/index.js +275 -0
- package/dist/crypto/logic-image-id.d.ts +3 -0
- package/dist/crypto/logic-image-id.js +27 -0
- package/dist/crypto/verifier.d.ts +29 -0
- package/dist/crypto/verifier.js +96 -0
- package/dist/economy/estimator.d.ts +53 -0
- package/dist/economy/estimator.js +69 -0
- package/dist/economy/index.d.ts +5 -0
- package/dist/economy/index.js +3 -0
- package/dist/economy/otel.d.ts +38 -0
- package/dist/economy/otel.js +100 -0
- package/dist/economy/telemetry.d.ts +77 -0
- package/dist/economy/telemetry.js +224 -0
- package/dist/gateway/hybrid.d.ts +23 -0
- package/dist/gateway/hybrid.js +199 -0
- package/dist/gateway/router.d.ts +69 -0
- package/dist/gateway/router.js +1036 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/mesh/index.d.ts +1 -0
- package/dist/mesh/index.js +1 -0
- package/dist/mesh/node.d.ts +129 -0
- package/dist/mesh/node.js +853 -0
- package/dist/prompts/adapters.d.ts +16 -0
- package/dist/prompts/adapters.js +55 -0
- package/dist/protocol/liop_core.proto +44 -0
- package/dist/rpc/client.d.ts +22 -0
- package/dist/rpc/client.js +40 -0
- package/dist/rpc/codec/lpm.d.ts +20 -0
- package/dist/rpc/codec/lpm.js +36 -0
- package/dist/rpc/crypto/aes.d.ts +22 -0
- package/dist/rpc/crypto/aes.js +47 -0
- package/dist/rpc/crypto/kyber.d.ts +27 -0
- package/dist/rpc/crypto/kyber.js +70 -0
- package/dist/rpc/proto.d.ts +2 -0
- package/dist/rpc/proto.js +33 -0
- package/dist/rpc/server.d.ts +13 -0
- package/dist/rpc/server.js +50 -0
- package/dist/rpc/tls.d.ts +26 -0
- package/dist/rpc/tls.js +54 -0
- package/dist/rpc/types.d.ts +28 -0
- package/dist/rpc/types.js +5 -0
- package/dist/sandbox/guardian.d.ts +18 -0
- package/dist/sandbox/guardian.js +35 -0
- package/dist/sandbox/wasi.d.ts +36 -0
- package/dist/sandbox/wasi.js +179 -0
- package/dist/security/guardian.d.ts +22 -0
- package/dist/security/guardian.js +52 -0
- package/dist/security/zk.d.ts +37 -0
- package/dist/security/zk.js +66 -0
- package/dist/server/index.d.ts +184 -0
- package/dist/server/index.js +933 -0
- package/dist/server/pii.d.ts +40 -0
- package/dist/server/pii.js +266 -0
- package/dist/types.d.ts +145 -0
- package/dist/types.js +26 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.js +70 -0
- package/dist/utils/mcpCompact.d.ts +11 -0
- package/dist/utils/mcpCompact.js +29 -0
- package/dist/workers/logic-execution.d.ts +17 -0
- package/dist/workers/logic-execution.js +121 -0
- package/dist/workers/zk-verifier.d.ts +20 -0
- package/dist/workers/zk-verifier.js +84 -0
- package/package.json +147 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MeshNode } from "../mesh/index.js";
|
|
2
|
+
import type { LiopServer } from "../server/index.js";
|
|
3
|
+
import { LiopMcpRouter } from "./router.js";
|
|
4
|
+
/**
|
|
5
|
+
* LIOP Hybrid Gateway
|
|
6
|
+
* High-level orchestration for connecting MCP (JSON-RPC) clients to the LIOP Mesh.
|
|
7
|
+
*/
|
|
8
|
+
export declare class LiopHybridGateway {
|
|
9
|
+
private liopServer;
|
|
10
|
+
private meshNode;
|
|
11
|
+
private netServer;
|
|
12
|
+
private h2Server;
|
|
13
|
+
private h1Server;
|
|
14
|
+
private router;
|
|
15
|
+
constructor(liopServer: LiopServer, meshNode?: MeshNode | null, rpcPort?: number);
|
|
16
|
+
private setupH2Routes;
|
|
17
|
+
private setupH1Routes;
|
|
18
|
+
private handleGrpcStream;
|
|
19
|
+
private handleMcpH2Stream;
|
|
20
|
+
listen(port: number, host?: string): Promise<number>;
|
|
21
|
+
stop(): Promise<void>;
|
|
22
|
+
getRouter(): LiopMcpRouter;
|
|
23
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as http from "node:http";
|
|
2
|
+
import * as http2 from "node:http2";
|
|
3
|
+
import * as net from "node:net";
|
|
4
|
+
import { log } from "../utils/logger.js";
|
|
5
|
+
import { LiopMcpRouter } from "./router.js";
|
|
6
|
+
/**
|
|
7
|
+
* LIOP Hybrid Gateway
|
|
8
|
+
* High-level orchestration for connecting MCP (JSON-RPC) clients to the LIOP Mesh.
|
|
9
|
+
*/
|
|
10
|
+
export class LiopHybridGateway {
|
|
11
|
+
liopServer;
|
|
12
|
+
meshNode;
|
|
13
|
+
netServer;
|
|
14
|
+
h2Server;
|
|
15
|
+
h1Server;
|
|
16
|
+
router;
|
|
17
|
+
constructor(liopServer, meshNode = null, rpcPort = 50051) {
|
|
18
|
+
this.liopServer = liopServer;
|
|
19
|
+
this.meshNode = meshNode;
|
|
20
|
+
// Initialize the Universal Router
|
|
21
|
+
this.router = new LiopMcpRouter(this.liopServer, this.meshNode, rpcPort);
|
|
22
|
+
// Internal HTTP/2 Server (for Native gRPC Proxying)
|
|
23
|
+
this.h2Server = http2.createServer();
|
|
24
|
+
this.setupH2Routes();
|
|
25
|
+
// Internal HTTP/1 Server (for Browser/MCP)
|
|
26
|
+
this.h1Server = http.createServer();
|
|
27
|
+
this.setupH1Routes();
|
|
28
|
+
// Primary Multiplexer (L4)
|
|
29
|
+
this.netServer = net.createServer((socket) => {
|
|
30
|
+
socket.once("data", (buffer) => {
|
|
31
|
+
const isHttp2 = buffer.toString().startsWith("PRI * HTTP/2.0");
|
|
32
|
+
log.info(`[LIOP-Gateway] Incoming L4 Connection. Protocol: ${isHttp2 ? "HTTP/2 (gRPC)" : "HTTP/1.1 (MCP)"}`);
|
|
33
|
+
if (isHttp2) {
|
|
34
|
+
this.h2Server.emit("connection", socket);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
this.h1Server.emit("connection", socket);
|
|
38
|
+
}
|
|
39
|
+
socket.unshift(buffer);
|
|
40
|
+
});
|
|
41
|
+
socket.on("error", (err) => log.error(`[LIOP-Gateway] NetServer Socket Error: ${err.message}`));
|
|
42
|
+
});
|
|
43
|
+
// Attach error listeners to sub-servers to catch silent failures
|
|
44
|
+
this.h1Server.on("error", (err) => log.error(`[LIOP-Gateway] H1 Server Error: ${err.message}`));
|
|
45
|
+
this.h2Server.on("error", (err) => log.error(`[LIOP-Gateway] H2 Server Error: ${err.message}`));
|
|
46
|
+
log.info("[LIOP-Gateway] Hybrid adapter initialized.");
|
|
47
|
+
}
|
|
48
|
+
setupH2Routes() {
|
|
49
|
+
this.h2Server.on("stream", (stream, headers) => {
|
|
50
|
+
const contentType = headers["content-type"];
|
|
51
|
+
const path = headers[":path"];
|
|
52
|
+
if (contentType === "application/grpc") {
|
|
53
|
+
this.handleGrpcStream(stream);
|
|
54
|
+
}
|
|
55
|
+
else if (path === "/mcp") {
|
|
56
|
+
this.handleMcpH2Stream(stream, headers);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
setupH1Routes() {
|
|
61
|
+
this.h1Server.on("request", async (req, res) => {
|
|
62
|
+
const url = req.url || "";
|
|
63
|
+
const method = req.method;
|
|
64
|
+
if (method === "GET" &&
|
|
65
|
+
(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
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
87
|
+
res.end(`
|
|
88
|
+
<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">
|
|
89
|
+
<div style="background:#1e293b;padding:40px;border-radius:16px;border:1px solid #38bdf8;text-align:center;box-shadow:0 20px 25px -5px rgba(0,0,0,0.1)">
|
|
90
|
+
<h1 style="color:#38bdf8;margin-top:0">LIOP Protocol Transformer</h1>
|
|
91
|
+
<p style="opacity:0.8;font-weight:600">L4/L7 Transcoding: JSON-RPC ↔ gRPC</p>
|
|
92
|
+
<p style="opacity:0.6;font-size:14px">Active Protections: Kyber768 + AES-256-GCM + ZK-Proof Ready</p>
|
|
93
|
+
<div style="background:#0f172a;padding:15px;border-radius:8px;margin-top:20px;border:1px dashed #334155">
|
|
94
|
+
<code style="color:#10b981">Endpoint: http://localhost:3000/mcp</code>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
</body>
|
|
98
|
+
`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (url === "/mcp" && method === "POST") {
|
|
102
|
+
let body = "";
|
|
103
|
+
req.on("data", (chunk) => (body += chunk.toString()));
|
|
104
|
+
req.on("end", async () => {
|
|
105
|
+
try {
|
|
106
|
+
const jsonRequest = JSON.parse(body);
|
|
107
|
+
const response = await this.router.dispatch(jsonRequest);
|
|
108
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
109
|
+
res.end(JSON.stringify(response));
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
log.info(`[LIOP-Gateway] Error processing JSON-RPC payload: ${e.message}`);
|
|
113
|
+
res.writeHead(400);
|
|
114
|
+
res.end(JSON.stringify({
|
|
115
|
+
jsonrpc: "2.0",
|
|
116
|
+
error: { code: -32700, message: "Parse error" },
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
res.writeHead(404);
|
|
123
|
+
res.end("Not Found");
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
handleGrpcStream(stream) {
|
|
128
|
+
stream.on("data", (chunk) => {
|
|
129
|
+
// biome-ignore lint/suspicious/noExplicitAny: Standard gRPC stream data is Buffer
|
|
130
|
+
const data = chunk;
|
|
131
|
+
if (data)
|
|
132
|
+
log.info(`[LIOP-Gateway] Native gRPC Proxy passing ${data.length} bytes`);
|
|
133
|
+
});
|
|
134
|
+
stream.respond({ ":status": 200, "content-type": "application/grpc" });
|
|
135
|
+
stream.end();
|
|
136
|
+
}
|
|
137
|
+
handleMcpH2Stream(stream, _headers) {
|
|
138
|
+
let body = "";
|
|
139
|
+
stream.on("data", (chunk) => (body += chunk.toString()));
|
|
140
|
+
stream.on("end", async () => {
|
|
141
|
+
try {
|
|
142
|
+
const response = await this.router.dispatch(JSON.parse(body));
|
|
143
|
+
if (response) {
|
|
144
|
+
stream.respond({
|
|
145
|
+
":status": 200,
|
|
146
|
+
"content-type": "application/json",
|
|
147
|
+
});
|
|
148
|
+
stream.end(JSON.stringify(response));
|
|
149
|
+
}
|
|
150
|
+
else
|
|
151
|
+
stream.close();
|
|
152
|
+
}
|
|
153
|
+
catch (_e) {
|
|
154
|
+
stream.respond({ ":status": 400 });
|
|
155
|
+
stream.end();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async listen(port, host = "0.0.0.0") {
|
|
160
|
+
if (this.meshNode) {
|
|
161
|
+
await this.meshNode.start();
|
|
162
|
+
// Announce all local tools to the DHT
|
|
163
|
+
const tools = this.liopServer.listTools();
|
|
164
|
+
for (const tool of tools) {
|
|
165
|
+
await this.meshNode.announceCapability(tool.name);
|
|
166
|
+
log.info(`[LIOP-Gateway] 📡 Announced local tool to Mesh: ${tool.name}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return new Promise((resolve, reject) => {
|
|
170
|
+
this.netServer.on("error", (err) => {
|
|
171
|
+
if (err.code === "EADDRINUSE") {
|
|
172
|
+
log.info(`[LIOP-Gateway] FATAL: Port ${port} is already in use by another process.`);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
log.error(`[LIOP-Gateway] Binding Error: ${err.message}`);
|
|
176
|
+
}
|
|
177
|
+
reject(err);
|
|
178
|
+
});
|
|
179
|
+
this.netServer.listen(port, host, () => {
|
|
180
|
+
const addr = this.netServer.address();
|
|
181
|
+
const actualHost = typeof addr === "string" ? addr : addr?.address || host;
|
|
182
|
+
const assignedPort = typeof addr === "string" ? port : addr?.port || port;
|
|
183
|
+
log.info(`[LIOP-Gateway] ✅ Transformer Mesh Gateway READY and listening on ${actualHost}:${assignedPort}`);
|
|
184
|
+
resolve(assignedPort);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
async stop() {
|
|
189
|
+
if (this.meshNode) {
|
|
190
|
+
await this.meshNode.stop();
|
|
191
|
+
}
|
|
192
|
+
this.netServer.close();
|
|
193
|
+
this.h2Server.close();
|
|
194
|
+
this.h1Server.close();
|
|
195
|
+
}
|
|
196
|
+
getRouter() {
|
|
197
|
+
return this.router;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { LiopVerifier } from "../crypto/verifier.js";
|
|
2
|
+
import type { MeshNode } from "../mesh/index.js";
|
|
3
|
+
import type { LiopServer } from "../server/index.js";
|
|
4
|
+
import type { McpRequest, McpResponse } from "../types.js";
|
|
5
|
+
/**
|
|
6
|
+
* LIOP MCP Router
|
|
7
|
+
*
|
|
8
|
+
* Core logic for routing MCP requests to local or remote LIOP providers.
|
|
9
|
+
* Decoupled from transport (HTTP/Stdio).
|
|
10
|
+
*
|
|
11
|
+
* All tool discovery and port resolution is DYNAMIC via the
|
|
12
|
+
* /liop/manifest/1.0.0 protocol stream over Kademlia DHT.
|
|
13
|
+
*/
|
|
14
|
+
export declare class LiopMcpRouter {
|
|
15
|
+
private liopServer;
|
|
16
|
+
private meshNode;
|
|
17
|
+
private defaultRpcPort;
|
|
18
|
+
/** Cached manifests from remote peers. Key = PeerID */
|
|
19
|
+
private manifestCache;
|
|
20
|
+
/** Guards against concurrent discovery storms */
|
|
21
|
+
private currentDiscovery;
|
|
22
|
+
/** Verifier for Tier-0 integrity checks */
|
|
23
|
+
verifier: LiopVerifier;
|
|
24
|
+
/** Callback when new remote tools are discovered */
|
|
25
|
+
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
|
+
constructor(liopServer: LiopServer, meshNode?: MeshNode | null, defaultRpcPort?: number);
|
|
32
|
+
private shouldSkipManifestQuery;
|
|
33
|
+
private recordManifestQuerySuccess;
|
|
34
|
+
private recordManifestQueryFailure;
|
|
35
|
+
dispatch(request: McpRequest): Promise<McpResponse | null>;
|
|
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;
|
|
41
|
+
/**
|
|
42
|
+
* Discovers and caches manifests from all remote LIOP providers in the mesh.
|
|
43
|
+
* Uses Kademlia DHT to find "liop:manifest" providers, then opens
|
|
44
|
+
* /liop/manifest/1.0.0 protocol streams to retrieve their full metadata.
|
|
45
|
+
*/
|
|
46
|
+
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
|
+
/**
|
|
53
|
+
* Returns all remote tools discovered via the manifest protocol.
|
|
54
|
+
*/
|
|
55
|
+
private getRemoteTools;
|
|
56
|
+
/**
|
|
57
|
+
* Returns all remote resources discovered via the manifest protocol.
|
|
58
|
+
*/
|
|
59
|
+
private getRemoteResources;
|
|
60
|
+
/**
|
|
61
|
+
* Resolves the gRPC target (host:port) AND the peerId for a given tool name
|
|
62
|
+
* by searching the manifest cache. Supports exact names and suffixed names.
|
|
63
|
+
*/
|
|
64
|
+
private resolveManifestTarget;
|
|
65
|
+
private transcodeMcpToLiop;
|
|
66
|
+
private routeToRemoteProvider;
|
|
67
|
+
private performTranscoding;
|
|
68
|
+
private encryptWithNonce;
|
|
69
|
+
}
|