@nekzus/liop 1.3.0-alpha.1 → 2.0.0-alpha.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 +41 -17
- package/dist/bin/agent.d.ts +0 -1
- package/dist/bin/agent.js +5 -306
- package/dist/bin/agent.js.map +1 -0
- package/dist/{bridge/stream.d.ts → bridge.d.ts} +44 -3
- package/dist/bridge.js +2 -0
- package/dist/bridge.js.map +1 -0
- package/dist/chunk-4ABAFG44.js +33 -0
- package/dist/chunk-4ABAFG44.js.map +1 -0
- package/dist/chunk-ANFXJGMP.js +2 -0
- package/dist/chunk-ANFXJGMP.js.map +1 -0
- package/dist/chunk-DBXGYHKY.js +2 -0
- package/dist/chunk-DBXGYHKY.js.map +1 -0
- package/dist/chunk-HM77MWB6.js +2 -0
- package/dist/chunk-HM77MWB6.js.map +1 -0
- package/dist/chunk-HNDVAKEK.js +24 -0
- package/dist/chunk-HNDVAKEK.js.map +1 -0
- package/dist/chunk-HQZHZM6U.js +2 -0
- package/dist/chunk-HQZHZM6U.js.map +1 -0
- package/dist/chunk-P52IE4L6.js +2 -0
- package/dist/chunk-P52IE4L6.js.map +1 -0
- package/dist/chunk-PIBCW4BD.js +13 -0
- package/dist/chunk-PIBCW4BD.js.map +1 -0
- package/dist/chunk-PPCOS2NU.js +2 -0
- package/dist/chunk-PPCOS2NU.js.map +1 -0
- package/dist/chunk-RWRRBYG4.js +2 -0
- package/dist/chunk-RWRRBYG4.js.map +1 -0
- package/dist/chunk-S6RJHZV2.js +2 -0
- package/dist/chunk-S6RJHZV2.js.map +1 -0
- package/dist/chunk-UVTEJYHN.js +2 -0
- package/dist/chunk-UVTEJYHN.js.map +1 -0
- package/dist/chunk-X6FJATUE.js +29 -0
- package/dist/chunk-X6FJATUE.js.map +1 -0
- package/dist/chunk-XLVRRGOX.js +3 -0
- package/dist/chunk-XLVRRGOX.js.map +1 -0
- package/dist/client.d.ts +5 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/{gateway/router.d.ts → gateway.d.ts} +37 -5
- package/dist/gateway.js +2 -0
- package/dist/gateway.js.map +1 -0
- package/dist/{client/index.d.ts → index-CyxNLlz7.d.ts} +24 -5
- package/dist/index.d.ts +313 -12
- package/dist/index.js +31 -12
- package/dist/index.js.map +1 -0
- package/dist/kyber-2WDOTUQX.js +2 -0
- package/dist/kyber-2WDOTUQX.js.map +1 -0
- package/dist/{mesh/node.d.ts → mesh.d.ts} +5 -3
- package/dist/mesh.js +2 -0
- package/dist/mesh.js.map +1 -0
- package/dist/{server/index.d.ts → server.d.ts} +145 -10
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +17 -14
- package/dist/types.js +2 -26
- package/dist/types.js.map +1 -0
- package/dist/{crypto/verifier.d.ts → verifier-DTCD9imJ.d.ts} +3 -1
- package/dist/verifier-RQRYXA4C.js +2 -0
- package/dist/verifier-RQRYXA4C.js.map +1 -0
- package/dist/workers/logic-execution.d.ts +4 -2
- package/dist/workers/logic-execution.js +2 -123
- package/dist/workers/logic-execution.js.map +1 -0
- package/dist/workers/zk-verifier.d.ts +4 -2
- package/dist/workers/zk-verifier.js +2 -98
- package/dist/workers/zk-verifier.js.map +1 -0
- package/package.json +31 -17
- package/dist/bridge/index.d.ts +0 -37
- package/dist/bridge/index.js +0 -249
- package/dist/bridge/stream.js +0 -210
- package/dist/client/index.js +0 -275
- package/dist/crypto/logic-image-id.d.ts +0 -3
- package/dist/crypto/logic-image-id.js +0 -27
- package/dist/crypto/verifier.js +0 -97
- 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/errors.d.ts +0 -14
- package/dist/errors.js +0 -19
- package/dist/gateway/hybrid.d.ts +0 -23
- package/dist/gateway/hybrid.js +0 -199
- package/dist/gateway/router.js +0 -1036
- package/dist/mesh/index.d.ts +0 -1
- package/dist/mesh/index.js +0 -1
- package/dist/mesh/node.js +0 -853
- package/dist/prompts/adapters.d.ts +0 -16
- package/dist/prompts/adapters.js +0 -55
- package/dist/rpc/client.d.ts +0 -22
- package/dist/rpc/client.js +0 -40
- package/dist/rpc/codec/lpm.d.ts +0 -20
- package/dist/rpc/codec/lpm.js +0 -36
- package/dist/rpc/crypto/aes.d.ts +0 -22
- package/dist/rpc/crypto/aes.js +0 -47
- package/dist/rpc/crypto/kyber.d.ts +0 -27
- package/dist/rpc/crypto/kyber.js +0 -70
- package/dist/rpc/proto.d.ts +0 -2
- package/dist/rpc/proto.js +0 -33
- package/dist/rpc/server.d.ts +0 -13
- package/dist/rpc/server.js +0 -50
- package/dist/rpc/tls.d.ts +0 -26
- package/dist/rpc/tls.js +0 -54
- package/dist/rpc/types.d.ts +0 -28
- package/dist/rpc/types.js +0 -5
- package/dist/sandbox/guardian.d.ts +0 -18
- package/dist/sandbox/guardian.js +0 -58
- package/dist/sandbox/wasi.d.ts +0 -36
- package/dist/sandbox/wasi.js +0 -209
- package/dist/security/guardian.d.ts +0 -22
- package/dist/security/guardian.js +0 -52
- package/dist/security/zk.d.ts +0 -37
- package/dist/security/zk.js +0 -76
- package/dist/server/index.js +0 -937
- package/dist/server/pii.d.ts +0 -40
- package/dist/server/pii.js +0 -266
- 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
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/** Single MCP operation token footprint */
|
|
2
|
-
export interface TokenOperationMetric {
|
|
3
|
-
readonly type: "tools_list" | "tool_call" | "resource_read" | "resource_list" | "prompt_get" | "prompt_list" | "diagnostic";
|
|
4
|
-
readonly method: string;
|
|
5
|
-
readonly estimatedInputTokens: number;
|
|
6
|
-
readonly estimatedOutputTokens: number;
|
|
7
|
-
readonly timestamp: number;
|
|
8
|
-
readonly toolName?: string;
|
|
9
|
-
readonly peerId?: string;
|
|
10
|
-
readonly durationMs?: number;
|
|
11
|
-
}
|
|
12
|
-
/** Session-level aggregate report */
|
|
13
|
-
export interface TokenSessionReport {
|
|
14
|
-
readonly sessionId: string;
|
|
15
|
-
readonly operations: ReadonlyArray<TokenOperationMetric>;
|
|
16
|
-
readonly totalInputTokens: number;
|
|
17
|
-
readonly totalOutputTokens: number;
|
|
18
|
-
readonly estimatorName: string;
|
|
19
|
-
readonly sessionUptimeMs: number;
|
|
20
|
-
}
|
|
21
|
-
/** Per-tool aggregate breakdown */
|
|
22
|
-
export interface ToolTokenBreakdown {
|
|
23
|
-
readonly input: number;
|
|
24
|
-
readonly output: number;
|
|
25
|
-
readonly calls: number;
|
|
26
|
-
readonly avgDurationMs: number;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* TokenTelemetryEngine — Full-spectrum observational singleton for token cost measurement.
|
|
30
|
-
*
|
|
31
|
-
* Design principles:
|
|
32
|
-
* - Pure observer pattern: NEVER mutates MCP payloads or protocol flow.
|
|
33
|
-
* - Real tokenization: o200k_base BPE via gpt-tokenizer (async init, sync counting).
|
|
34
|
-
* - OTel gen_ai.* emission: standard metrics via @opentelemetry/api (NoOp if no provider).
|
|
35
|
-
* - Error isolation: telemetry failures never propagate to protocol operations.
|
|
36
|
-
*/
|
|
37
|
-
export declare class TokenTelemetryEngine {
|
|
38
|
-
private static instance;
|
|
39
|
-
private operations;
|
|
40
|
-
private readonly sessionId;
|
|
41
|
-
private readonly startedAt;
|
|
42
|
-
private estimator;
|
|
43
|
-
private otelBridge;
|
|
44
|
-
private constructor();
|
|
45
|
-
/** Async upgrade from heuristic to real BPE tokenizer */
|
|
46
|
-
private initRealEstimator;
|
|
47
|
-
static getInstance(): TokenTelemetryEngine;
|
|
48
|
-
/**
|
|
49
|
-
* Count tokens in a string using the active estimator.
|
|
50
|
-
* Delegates to o200k_base BPE tokenizer (or heuristic fallback).
|
|
51
|
-
*/
|
|
52
|
-
countTokens(content: string): number;
|
|
53
|
-
/**
|
|
54
|
-
* Record a single MCP operation's token footprint.
|
|
55
|
-
* Emits both internal metrics and OTel gen_ai.* histograms.
|
|
56
|
-
*/
|
|
57
|
-
record(metric: Omit<TokenOperationMetric, "timestamp">): void;
|
|
58
|
-
/**
|
|
59
|
-
* @deprecated Use countTokens() instead. Kept for backward compatibility.
|
|
60
|
-
*/
|
|
61
|
-
estimateTokens(content: string): number;
|
|
62
|
-
/** Generate the full session report */
|
|
63
|
-
getReport(): TokenSessionReport;
|
|
64
|
-
/** Get per-tool token breakdown for diagnostic display */
|
|
65
|
-
getPerToolReport(): Map<string, ToolTokenBreakdown>;
|
|
66
|
-
/**
|
|
67
|
-
* Format a rich, human-readable summary block for LiopMeshStatus diagnostic.
|
|
68
|
-
* Returns empty string when no operations have been recorded.
|
|
69
|
-
*/
|
|
70
|
-
formatStatusBlock(): string;
|
|
71
|
-
/** Format milliseconds into human-readable uptime string */
|
|
72
|
-
private formatUptime;
|
|
73
|
-
/** Reset all recorded metrics (used in tests) */
|
|
74
|
-
reset(): void;
|
|
75
|
-
/** Destroy the singleton (used in tests to guarantee isolation) */
|
|
76
|
-
static destroy(): void;
|
|
77
|
-
}
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { createSyncTokenEstimator, createTokenEstimator, } from "./estimator.js";
|
|
2
|
-
import { LiopOTelBridge } from "./otel.js";
|
|
3
|
-
/**
|
|
4
|
-
* Maps operation types to OTel gen_ai.operation.name values.
|
|
5
|
-
* @see https://opentelemetry.io/docs/specs/semconv/gen-ai/
|
|
6
|
-
*/
|
|
7
|
-
const OTEL_OPERATION_MAP = {
|
|
8
|
-
tools_list: "chat",
|
|
9
|
-
tool_call: "execute_tool",
|
|
10
|
-
resource_read: "chat",
|
|
11
|
-
resource_list: "chat",
|
|
12
|
-
prompt_get: "chat",
|
|
13
|
-
prompt_list: "chat",
|
|
14
|
-
diagnostic: "chat",
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* TokenTelemetryEngine — Full-spectrum observational singleton for token cost measurement.
|
|
18
|
-
*
|
|
19
|
-
* Design principles:
|
|
20
|
-
* - Pure observer pattern: NEVER mutates MCP payloads or protocol flow.
|
|
21
|
-
* - Real tokenization: o200k_base BPE via gpt-tokenizer (async init, sync counting).
|
|
22
|
-
* - OTel gen_ai.* emission: standard metrics via @opentelemetry/api (NoOp if no provider).
|
|
23
|
-
* - Error isolation: telemetry failures never propagate to protocol operations.
|
|
24
|
-
*/
|
|
25
|
-
export class TokenTelemetryEngine {
|
|
26
|
-
static instance = null;
|
|
27
|
-
operations = [];
|
|
28
|
-
sessionId;
|
|
29
|
-
startedAt;
|
|
30
|
-
estimator;
|
|
31
|
-
otelBridge;
|
|
32
|
-
constructor() {
|
|
33
|
-
this.sessionId = crypto.randomUUID();
|
|
34
|
-
this.startedAt = Date.now();
|
|
35
|
-
// Start with sync heuristic estimator (available immediately)
|
|
36
|
-
this.estimator = createSyncTokenEstimator();
|
|
37
|
-
this.otelBridge = new LiopOTelBridge();
|
|
38
|
-
// Upgrade to real tokenizer asynchronously
|
|
39
|
-
this.initRealEstimator();
|
|
40
|
-
}
|
|
41
|
-
/** Async upgrade from heuristic to real BPE tokenizer */
|
|
42
|
-
initRealEstimator() {
|
|
43
|
-
createTokenEstimator()
|
|
44
|
-
.then((real) => {
|
|
45
|
-
this.estimator = real;
|
|
46
|
-
})
|
|
47
|
-
.catch(() => {
|
|
48
|
-
// Keep heuristic fallback — already assigned in constructor
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
static getInstance() {
|
|
52
|
-
if (!TokenTelemetryEngine.instance) {
|
|
53
|
-
TokenTelemetryEngine.instance = new TokenTelemetryEngine();
|
|
54
|
-
}
|
|
55
|
-
return TokenTelemetryEngine.instance;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Count tokens in a string using the active estimator.
|
|
59
|
-
* Delegates to o200k_base BPE tokenizer (or heuristic fallback).
|
|
60
|
-
*/
|
|
61
|
-
countTokens(content) {
|
|
62
|
-
try {
|
|
63
|
-
return this.estimator.countTokens(content);
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
// Fallback: never let counting failures break protocol flow
|
|
67
|
-
return Math.ceil(content.length / 4);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Record a single MCP operation's token footprint.
|
|
72
|
-
* Emits both internal metrics and OTel gen_ai.* histograms.
|
|
73
|
-
*/
|
|
74
|
-
record(metric) {
|
|
75
|
-
const fullMetric = {
|
|
76
|
-
...metric,
|
|
77
|
-
timestamp: Date.now(),
|
|
78
|
-
};
|
|
79
|
-
this.operations.push(fullMetric);
|
|
80
|
-
// Emit to OTel bridge (NoOp if no MeterProvider configured)
|
|
81
|
-
try {
|
|
82
|
-
const otelOp = OTEL_OPERATION_MAP[metric.type] || "chat";
|
|
83
|
-
if (metric.estimatedInputTokens > 0) {
|
|
84
|
-
this.otelBridge.recordTokens(metric.estimatedInputTokens, "input", otelOp, metric.toolName);
|
|
85
|
-
}
|
|
86
|
-
if (metric.estimatedOutputTokens > 0) {
|
|
87
|
-
this.otelBridge.recordTokens(metric.estimatedOutputTokens, "output", otelOp, metric.toolName);
|
|
88
|
-
}
|
|
89
|
-
if (metric.durationMs !== undefined) {
|
|
90
|
-
this.otelBridge.recordDuration(metric.durationMs, otelOp);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
// OTel emission failure must never affect protocol operations
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* @deprecated Use countTokens() instead. Kept for backward compatibility.
|
|
99
|
-
*/
|
|
100
|
-
estimateTokens(content) {
|
|
101
|
-
return this.countTokens(content);
|
|
102
|
-
}
|
|
103
|
-
/** Generate the full session report */
|
|
104
|
-
getReport() {
|
|
105
|
-
return {
|
|
106
|
-
sessionId: this.sessionId,
|
|
107
|
-
operations: [...this.operations],
|
|
108
|
-
totalInputTokens: this.operations.reduce((sum, op) => sum + op.estimatedInputTokens, 0),
|
|
109
|
-
totalOutputTokens: this.operations.reduce((sum, op) => sum + op.estimatedOutputTokens, 0),
|
|
110
|
-
estimatorName: this.estimator.name,
|
|
111
|
-
sessionUptimeMs: Date.now() - this.startedAt,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
/** Get per-tool token breakdown for diagnostic display */
|
|
115
|
-
getPerToolReport() {
|
|
116
|
-
const breakdown = new Map();
|
|
117
|
-
for (const op of this.operations) {
|
|
118
|
-
const key = op.toolName || op.method;
|
|
119
|
-
const existing = breakdown.get(key) || {
|
|
120
|
-
input: 0,
|
|
121
|
-
output: 0,
|
|
122
|
-
calls: 0,
|
|
123
|
-
avgDurationMs: 0,
|
|
124
|
-
};
|
|
125
|
-
const totalDuration = existing.avgDurationMs * existing.calls + (op.durationMs || 0);
|
|
126
|
-
const newCalls = existing.calls + 1;
|
|
127
|
-
breakdown.set(key, {
|
|
128
|
-
input: existing.input + op.estimatedInputTokens,
|
|
129
|
-
output: existing.output + op.estimatedOutputTokens,
|
|
130
|
-
calls: newCalls,
|
|
131
|
-
avgDurationMs: newCalls > 0 ? totalDuration / newCalls : 0,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
return breakdown;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Format a rich, human-readable summary block for LiopMeshStatus diagnostic.
|
|
138
|
-
* Returns empty string when no operations have been recorded.
|
|
139
|
-
*/
|
|
140
|
-
formatStatusBlock() {
|
|
141
|
-
const report = this.getReport();
|
|
142
|
-
if (report.operations.length === 0)
|
|
143
|
-
return "";
|
|
144
|
-
const uptimeStr = this.formatUptime(report.sessionUptimeMs);
|
|
145
|
-
const totalCombined = report.totalInputTokens + report.totalOutputTokens;
|
|
146
|
-
// Aggregate operations by type
|
|
147
|
-
const byType = new Map();
|
|
148
|
-
for (const op of report.operations) {
|
|
149
|
-
const key = op.type;
|
|
150
|
-
const existing = byType.get(key) || {
|
|
151
|
-
count: 0,
|
|
152
|
-
input: 0,
|
|
153
|
-
output: 0,
|
|
154
|
-
};
|
|
155
|
-
byType.set(key, {
|
|
156
|
-
count: existing.count + 1,
|
|
157
|
-
input: existing.input + op.estimatedInputTokens,
|
|
158
|
-
output: existing.output + op.estimatedOutputTokens,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
// Build type breakdown lines
|
|
162
|
-
const typeEntries = Array.from(byType.entries());
|
|
163
|
-
const typeLines = typeEntries.map(([type, data], idx) => {
|
|
164
|
-
const prefix = idx === typeEntries.length - 1 ? "│ └─" : "│ ├─";
|
|
165
|
-
const outputPart = data.output > 0 ? ` / ${data.output.toLocaleString()} out` : "";
|
|
166
|
-
return `${prefix} ${type} ×${data.count} → ${data.input.toLocaleString()} in${outputPart}`;
|
|
167
|
-
});
|
|
168
|
-
// Build per-tool breakdown
|
|
169
|
-
const toolReport = this.getPerToolReport();
|
|
170
|
-
const toolEntries = Array.from(toolReport.entries()).filter(([key]) => key !== "tools/list" && key !== "LiopMeshStatus");
|
|
171
|
-
const toolLines = [];
|
|
172
|
-
if (toolEntries.length > 0) {
|
|
173
|
-
toolLines.push("├─ By Tool:");
|
|
174
|
-
toolEntries.forEach(([name, data], idx) => {
|
|
175
|
-
const prefix = idx === toolEntries.length - 1 ? "│ └─" : "│ ├─";
|
|
176
|
-
const outputPart = data.output > 0 ? ` / ${data.output.toLocaleString()} out` : "";
|
|
177
|
-
const durationPart = data.avgDurationMs > 0 ? ` ~${Math.round(data.avgDurationMs)}ms` : "";
|
|
178
|
-
toolLines.push(`${prefix} ${name}: ${data.input.toLocaleString()} in${outputPart} (×${data.calls})${durationPart}`);
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
// Calculate average latency across all timed operations
|
|
182
|
-
const timedOps = report.operations.filter((op) => op.durationMs !== undefined);
|
|
183
|
-
const avgLatency = timedOps.length > 0
|
|
184
|
-
? Math.round(timedOps.reduce((sum, op) => sum + (op.durationMs || 0), 0) /
|
|
185
|
-
timedOps.length)
|
|
186
|
-
: 0;
|
|
187
|
-
const otelStatus = this.otelBridge.isActive()
|
|
188
|
-
? "gen_ai.client.token.usage → active"
|
|
189
|
-
: "disabled";
|
|
190
|
-
const lines = [
|
|
191
|
-
"\nToken Economy:",
|
|
192
|
-
`├─ Session: ${report.sessionId.slice(0, 8)} (${uptimeStr})`,
|
|
193
|
-
`├─ Estimator: ${report.estimatorName}`,
|
|
194
|
-
`├─ Operations: ${report.operations.length}`,
|
|
195
|
-
...typeLines,
|
|
196
|
-
`├─ Total: ${report.totalInputTokens.toLocaleString()} in / ${report.totalOutputTokens.toLocaleString()} out (${totalCombined.toLocaleString()} combined)`,
|
|
197
|
-
...toolLines,
|
|
198
|
-
...(avgLatency > 0 ? [`├─ Avg Latency: ${avgLatency}ms`] : []),
|
|
199
|
-
`└─ OTel: ${otelStatus}`,
|
|
200
|
-
];
|
|
201
|
-
return lines.join("\n");
|
|
202
|
-
}
|
|
203
|
-
/** Format milliseconds into human-readable uptime string */
|
|
204
|
-
formatUptime(ms) {
|
|
205
|
-
const seconds = Math.floor(ms / 1000);
|
|
206
|
-
if (seconds < 60)
|
|
207
|
-
return `${seconds}s`;
|
|
208
|
-
const minutes = Math.floor(seconds / 60);
|
|
209
|
-
const remainingSeconds = seconds % 60;
|
|
210
|
-
if (minutes < 60)
|
|
211
|
-
return `${minutes}m ${remainingSeconds}s`;
|
|
212
|
-
const hours = Math.floor(minutes / 60);
|
|
213
|
-
const remainingMinutes = minutes % 60;
|
|
214
|
-
return `${hours}h ${remainingMinutes}m`;
|
|
215
|
-
}
|
|
216
|
-
/** Reset all recorded metrics (used in tests) */
|
|
217
|
-
reset() {
|
|
218
|
-
this.operations = [];
|
|
219
|
-
}
|
|
220
|
-
/** Destroy the singleton (used in tests to guarantee isolation) */
|
|
221
|
-
static destroy() {
|
|
222
|
-
TokenTelemetryEngine.instance = null;
|
|
223
|
-
}
|
|
224
|
-
}
|
package/dist/errors.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export declare enum ErrorCode {
|
|
2
|
-
CapabilityViolation = "CapabilityViolation",
|
|
3
|
-
SandboxEscape = "SandboxEscape",
|
|
4
|
-
PiiLeak = "PiiLeak",
|
|
5
|
-
InvalidIntent = "InvalidIntent",
|
|
6
|
-
Throttled = "Throttled",
|
|
7
|
-
ZkVerificationFailed = "ZkVerificationFailed",
|
|
8
|
-
MeshUnavailable = "MeshUnavailable",
|
|
9
|
-
ConnectionFailed = "ConnectionFailed"
|
|
10
|
-
}
|
|
11
|
-
export declare class LiopError extends Error {
|
|
12
|
-
readonly code: ErrorCode;
|
|
13
|
-
constructor(code: ErrorCode, message: string);
|
|
14
|
-
}
|
package/dist/errors.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export var ErrorCode;
|
|
2
|
-
(function (ErrorCode) {
|
|
3
|
-
ErrorCode["CapabilityViolation"] = "CapabilityViolation";
|
|
4
|
-
ErrorCode["SandboxEscape"] = "SandboxEscape";
|
|
5
|
-
ErrorCode["PiiLeak"] = "PiiLeak";
|
|
6
|
-
ErrorCode["InvalidIntent"] = "InvalidIntent";
|
|
7
|
-
ErrorCode["Throttled"] = "Throttled";
|
|
8
|
-
ErrorCode["ZkVerificationFailed"] = "ZkVerificationFailed";
|
|
9
|
-
ErrorCode["MeshUnavailable"] = "MeshUnavailable";
|
|
10
|
-
ErrorCode["ConnectionFailed"] = "ConnectionFailed";
|
|
11
|
-
})(ErrorCode || (ErrorCode = {}));
|
|
12
|
-
export class LiopError extends Error {
|
|
13
|
-
code;
|
|
14
|
-
constructor(code, message) {
|
|
15
|
-
super(message);
|
|
16
|
-
this.name = "LiopError";
|
|
17
|
-
this.code = code;
|
|
18
|
-
}
|
|
19
|
-
}
|
package/dist/gateway/hybrid.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
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
|
-
}
|
package/dist/gateway/hybrid.js
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
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
|
-
}
|