@nekzus/liop 2.4.0-alpha.23 → 2.4.0-alpha.25
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 -10
- package/dist/bin/agent.js +61 -23
- package/dist/bridge.d.ts +3 -3
- package/dist/bridge.js +3 -3
- package/dist/{chunk-WPTOJYN5.js → chunk-3664H3CV.js} +14 -59
- package/dist/{chunk-E7RSX476.js → chunk-6MYJBM2E.js} +4 -4
- package/dist/{chunk-AMSFSS2I.js → chunk-DSOB2JKM.js} +20 -10
- package/dist/{chunk-OHMZZMMC.js → chunk-ET6VRUK2.js} +3 -3
- package/dist/{chunk-P34HDRN5.js → chunk-FIVRGOA4.js} +69 -2
- package/dist/{chunk-KB3HUVMD.js → chunk-IHKKWXHJ.js} +24 -25
- package/dist/chunk-JPWC6XG6.js +941 -0
- package/dist/{chunk-YLFNJQI2.js → chunk-KR5UZUEY.js} +24 -3
- package/dist/chunk-NXCAFF73.js +59 -0
- package/dist/{chunk-7BSCUYUE.js → chunk-R52TZEIL.js} +8 -3
- package/dist/{chunk-3WKFZQ34.js → chunk-S3RAZTEM.js} +11 -7
- package/dist/{chunk-PUDETPL4.js → chunk-V47P2AQR.js} +5 -3
- package/dist/{chunk-E2CFIWD6.js → chunk-WXOWJXY6.js} +4 -4
- package/dist/{chunk-ZRWNMP5L.js → chunk-WXYDFCIW.js} +139 -11
- package/dist/{chunk-T2QDHVUD.js → chunk-ZU3WVVLC.js} +21 -12
- package/dist/client.d.ts +4 -4
- package/dist/client.js +6 -6
- package/dist/gateway.d.ts +5 -5
- package/dist/gateway.js +8 -7
- package/dist/{hybrid-B7EjCj3q.d.ts → hybrid-BZpCiUaV.d.ts} +3 -3
- package/dist/{index-DDwiS7tf.d.ts → index-BYDtRGue.d.ts} +3 -3
- package/dist/{index-D2P6Z_hP.d.ts → index-ByzjpRCk.d.ts} +6 -1
- package/dist/index.d.ts +15 -10
- package/dist/index.js +15 -14
- package/dist/mesh.js +1 -1
- package/dist/server.d.ts +3 -3
- package/dist/server.js +6 -5
- package/dist/{types-rxL19f0l.d.ts → types-29zv9X1V.d.ts} +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +2 -2
- package/dist/verifier-55HW6AFN.js +6 -0
- package/dist/{verifier-DTn1LXDU.d.ts → verifier-DqZ9MQ9l.d.ts} +34 -5
- package/dist/workers/logic-execution.d.ts +2 -1
- package/dist/workers/logic-execution.js +38 -9
- package/dist/workers/zk-verifier.d.ts +1 -1
- package/dist/workers/zk-verifier.js +35 -5
- package/dist/{zk-CYImPsa6.d.ts → zk-DzYNWBgo.d.ts} +14 -1
- package/package.json +6 -2
- package/dist/bin/agent.js.map +0 -1
- package/dist/bridge.js.map +0 -1
- package/dist/chunk-3QH44NKZ.js.map +0 -1
- package/dist/chunk-3WKFZQ34.js.map +0 -1
- package/dist/chunk-7BSCUYUE.js.map +0 -1
- package/dist/chunk-7PITYWOV.js.map +0 -1
- package/dist/chunk-AMSFSS2I.js.map +0 -1
- package/dist/chunk-E2CFIWD6.js.map +0 -1
- package/dist/chunk-E7RSX476.js.map +0 -1
- package/dist/chunk-FTF6AMF6.js.map +0 -1
- package/dist/chunk-GFGSHQN5.js +0 -206884
- package/dist/chunk-GFGSHQN5.js.map +0 -1
- package/dist/chunk-IK7CGWAZ.js.map +0 -1
- package/dist/chunk-K3DGJLUY.js.map +0 -1
- package/dist/chunk-KB3HUVMD.js.map +0 -1
- package/dist/chunk-OHMZZMMC.js.map +0 -1
- package/dist/chunk-P34HDRN5.js.map +0 -1
- package/dist/chunk-PUDETPL4.js.map +0 -1
- package/dist/chunk-Q3FKHJ3B.js.map +0 -1
- package/dist/chunk-T2QDHVUD.js.map +0 -1
- package/dist/chunk-WPTOJYN5.js.map +0 -1
- package/dist/chunk-Y62GORQF.js.map +0 -1
- package/dist/chunk-YLFNJQI2.js.map +0 -1
- package/dist/chunk-ZP3VVXOI.js.map +0 -1
- package/dist/chunk-ZRWNMP5L.js.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/gateway.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/kyber-CGOA7Q6A.js.map +0 -1
- package/dist/mesh.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/verifier-UBJTZQSA.js +0 -6
- package/dist/verifier-UBJTZQSA.js.map +0 -1
- package/dist/workers/logic-execution.js.map +0 -1
- package/dist/workers/zk-verifier.js.map +0 -1
|
@@ -0,0 +1,941 @@
|
|
|
1
|
+
import { tokensInputTotal, tokensOutputTotal, tokensSavedTotal, operationDurationMs } from './chunk-Q3FKHJ3B.js';
|
|
2
|
+
import { log } from './chunk-K3DGJLUY.js';
|
|
3
|
+
import { countTokens, setMergeCacheSize } from 'gpt-tokenizer/model/gpt-4o';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as grpc from '@grpc/grpc-js';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import * as protoLoader from '@grpc/proto-loader';
|
|
9
|
+
|
|
10
|
+
var RealTokenEstimator = class {
|
|
11
|
+
name = "o200k_base";
|
|
12
|
+
countFn;
|
|
13
|
+
constructor(countFn, setMergeCacheSizeFn) {
|
|
14
|
+
this.countFn = countFn;
|
|
15
|
+
if (setMergeCacheSizeFn) {
|
|
16
|
+
try {
|
|
17
|
+
setMergeCacheSizeFn(1e4);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
countTokens(text) {
|
|
23
|
+
if (text.length === 0) return 0;
|
|
24
|
+
return this.countFn(text);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var HeuristicTokenEstimator = class {
|
|
28
|
+
name = "heuristic (chars/4)";
|
|
29
|
+
countTokens(text) {
|
|
30
|
+
if (text.length === 0) return 0;
|
|
31
|
+
return Math.ceil(text.length / 4);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
async function createTokenEstimator() {
|
|
35
|
+
try {
|
|
36
|
+
const estimator = new RealTokenEstimator(countTokens, setMergeCacheSize);
|
|
37
|
+
log.debug("[LIOP-Economy] Token estimator initialized: o200k_base");
|
|
38
|
+
return estimator;
|
|
39
|
+
} catch {
|
|
40
|
+
log.info(
|
|
41
|
+
"[LIOP-Economy] Inlined tokenizer initialization error, falling back to heuristic estimator"
|
|
42
|
+
);
|
|
43
|
+
return new HeuristicTokenEstimator();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function createSyncTokenEstimator() {
|
|
47
|
+
try {
|
|
48
|
+
return new RealTokenEstimator(countTokens, setMergeCacheSize);
|
|
49
|
+
} catch {
|
|
50
|
+
return new HeuristicTokenEstimator();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/version.js
|
|
55
|
+
var VERSION = "1.9.1";
|
|
56
|
+
|
|
57
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/internal/semver.js
|
|
58
|
+
var re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;
|
|
59
|
+
function _makeCompatibilityCheck(ownVersion) {
|
|
60
|
+
const acceptedVersions = /* @__PURE__ */ new Set([ownVersion]);
|
|
61
|
+
const rejectedVersions = /* @__PURE__ */ new Set();
|
|
62
|
+
const myVersionMatch = ownVersion.match(re);
|
|
63
|
+
if (!myVersionMatch) {
|
|
64
|
+
return () => false;
|
|
65
|
+
}
|
|
66
|
+
const ownVersionParsed = {
|
|
67
|
+
major: +myVersionMatch[1],
|
|
68
|
+
minor: +myVersionMatch[2],
|
|
69
|
+
patch: +myVersionMatch[3],
|
|
70
|
+
prerelease: myVersionMatch[4]
|
|
71
|
+
};
|
|
72
|
+
if (ownVersionParsed.prerelease != null) {
|
|
73
|
+
return function isExactmatch(globalVersion) {
|
|
74
|
+
return globalVersion === ownVersion;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function _reject(v) {
|
|
78
|
+
rejectedVersions.add(v);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
function _accept(v) {
|
|
82
|
+
acceptedVersions.add(v);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return function isCompatible2(globalVersion) {
|
|
86
|
+
if (acceptedVersions.has(globalVersion)) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
if (rejectedVersions.has(globalVersion)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const globalVersionMatch = globalVersion.match(re);
|
|
93
|
+
if (!globalVersionMatch) {
|
|
94
|
+
return _reject(globalVersion);
|
|
95
|
+
}
|
|
96
|
+
const globalVersionParsed = {
|
|
97
|
+
major: +globalVersionMatch[1],
|
|
98
|
+
minor: +globalVersionMatch[2],
|
|
99
|
+
patch: +globalVersionMatch[3],
|
|
100
|
+
prerelease: globalVersionMatch[4]
|
|
101
|
+
};
|
|
102
|
+
if (globalVersionParsed.prerelease != null) {
|
|
103
|
+
return _reject(globalVersion);
|
|
104
|
+
}
|
|
105
|
+
if (ownVersionParsed.major !== globalVersionParsed.major) {
|
|
106
|
+
return _reject(globalVersion);
|
|
107
|
+
}
|
|
108
|
+
if (ownVersionParsed.major === 0) {
|
|
109
|
+
if (ownVersionParsed.minor === globalVersionParsed.minor && ownVersionParsed.patch <= globalVersionParsed.patch) {
|
|
110
|
+
return _accept(globalVersion);
|
|
111
|
+
}
|
|
112
|
+
return _reject(globalVersion);
|
|
113
|
+
}
|
|
114
|
+
if (ownVersionParsed.minor <= globalVersionParsed.minor) {
|
|
115
|
+
return _accept(globalVersion);
|
|
116
|
+
}
|
|
117
|
+
return _reject(globalVersion);
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
var isCompatible = _makeCompatibilityCheck(VERSION);
|
|
121
|
+
|
|
122
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/internal/global-utils.js
|
|
123
|
+
var major = VERSION.split(".")[0];
|
|
124
|
+
var GLOBAL_OPENTELEMETRY_API_KEY = /* @__PURE__ */ Symbol.for(`opentelemetry.js.api.${major}`);
|
|
125
|
+
var _global = typeof globalThis === "object" ? globalThis : typeof self === "object" ? self : typeof window === "object" ? window : typeof global === "object" ? global : {};
|
|
126
|
+
function registerGlobal(type, instance, diag, allowOverride = false) {
|
|
127
|
+
var _a;
|
|
128
|
+
const api = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a !== void 0 ? _a : {
|
|
129
|
+
version: VERSION
|
|
130
|
+
};
|
|
131
|
+
if (!allowOverride && api[type]) {
|
|
132
|
+
const err = new Error(`@opentelemetry/api: Attempted duplicate registration of API: ${type}`);
|
|
133
|
+
diag.error(err.stack || err.message);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (api.version !== VERSION) {
|
|
137
|
+
const err = new Error(`@opentelemetry/api: Registration of version v${api.version} for ${type} does not match previously registered API v${VERSION}`);
|
|
138
|
+
diag.error(err.stack || err.message);
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
api[type] = instance;
|
|
142
|
+
diag.debug(`@opentelemetry/api: Registered a global for ${type} v${VERSION}.`);
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
function getGlobal(type) {
|
|
146
|
+
var _a, _b;
|
|
147
|
+
const globalVersion = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a === void 0 ? void 0 : _a.version;
|
|
148
|
+
if (!globalVersion || !isCompatible(globalVersion)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
return (_b = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b === void 0 ? void 0 : _b[type];
|
|
152
|
+
}
|
|
153
|
+
function unregisterGlobal(type, diag) {
|
|
154
|
+
diag.debug(`@opentelemetry/api: Unregistering a global for ${type} v${VERSION}.`);
|
|
155
|
+
const api = _global[GLOBAL_OPENTELEMETRY_API_KEY];
|
|
156
|
+
if (api) {
|
|
157
|
+
delete api[type];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js
|
|
162
|
+
var DiagComponentLogger = class {
|
|
163
|
+
constructor(props) {
|
|
164
|
+
this._namespace = props.namespace || "DiagComponentLogger";
|
|
165
|
+
}
|
|
166
|
+
debug(...args) {
|
|
167
|
+
return logProxy("debug", this._namespace, args);
|
|
168
|
+
}
|
|
169
|
+
error(...args) {
|
|
170
|
+
return logProxy("error", this._namespace, args);
|
|
171
|
+
}
|
|
172
|
+
info(...args) {
|
|
173
|
+
return logProxy("info", this._namespace, args);
|
|
174
|
+
}
|
|
175
|
+
warn(...args) {
|
|
176
|
+
return logProxy("warn", this._namespace, args);
|
|
177
|
+
}
|
|
178
|
+
verbose(...args) {
|
|
179
|
+
return logProxy("verbose", this._namespace, args);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
function logProxy(funcName, namespace, args) {
|
|
183
|
+
const logger = getGlobal("diag");
|
|
184
|
+
if (!logger) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
return logger[funcName](namespace, ...args);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/diag/types.js
|
|
191
|
+
var DiagLogLevel;
|
|
192
|
+
(function(DiagLogLevel2) {
|
|
193
|
+
DiagLogLevel2[DiagLogLevel2["NONE"] = 0] = "NONE";
|
|
194
|
+
DiagLogLevel2[DiagLogLevel2["ERROR"] = 30] = "ERROR";
|
|
195
|
+
DiagLogLevel2[DiagLogLevel2["WARN"] = 50] = "WARN";
|
|
196
|
+
DiagLogLevel2[DiagLogLevel2["INFO"] = 60] = "INFO";
|
|
197
|
+
DiagLogLevel2[DiagLogLevel2["DEBUG"] = 70] = "DEBUG";
|
|
198
|
+
DiagLogLevel2[DiagLogLevel2["VERBOSE"] = 80] = "VERBOSE";
|
|
199
|
+
DiagLogLevel2[DiagLogLevel2["ALL"] = 9999] = "ALL";
|
|
200
|
+
})(DiagLogLevel || (DiagLogLevel = {}));
|
|
201
|
+
|
|
202
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js
|
|
203
|
+
function createLogLevelDiagLogger(maxLevel, logger) {
|
|
204
|
+
if (maxLevel < DiagLogLevel.NONE) {
|
|
205
|
+
maxLevel = DiagLogLevel.NONE;
|
|
206
|
+
} else if (maxLevel > DiagLogLevel.ALL) {
|
|
207
|
+
maxLevel = DiagLogLevel.ALL;
|
|
208
|
+
}
|
|
209
|
+
logger = logger || {};
|
|
210
|
+
function _filterFunc(funcName, theLevel) {
|
|
211
|
+
const theFunc = logger[funcName];
|
|
212
|
+
if (typeof theFunc === "function" && maxLevel >= theLevel) {
|
|
213
|
+
return theFunc.bind(logger);
|
|
214
|
+
}
|
|
215
|
+
return function() {
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
error: _filterFunc("error", DiagLogLevel.ERROR),
|
|
220
|
+
warn: _filterFunc("warn", DiagLogLevel.WARN),
|
|
221
|
+
info: _filterFunc("info", DiagLogLevel.INFO),
|
|
222
|
+
debug: _filterFunc("debug", DiagLogLevel.DEBUG),
|
|
223
|
+
verbose: _filterFunc("verbose", DiagLogLevel.VERBOSE)
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/api/diag.js
|
|
228
|
+
var API_NAME = "diag";
|
|
229
|
+
var DiagAPI = class _DiagAPI {
|
|
230
|
+
/** Get the singleton instance of the DiagAPI API */
|
|
231
|
+
static instance() {
|
|
232
|
+
if (!this._instance) {
|
|
233
|
+
this._instance = new _DiagAPI();
|
|
234
|
+
}
|
|
235
|
+
return this._instance;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Private internal constructor
|
|
239
|
+
* @private
|
|
240
|
+
*/
|
|
241
|
+
constructor() {
|
|
242
|
+
function _logProxy(funcName) {
|
|
243
|
+
return function(...args) {
|
|
244
|
+
const logger = getGlobal("diag");
|
|
245
|
+
if (!logger)
|
|
246
|
+
return;
|
|
247
|
+
return logger[funcName](...args);
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const self2 = this;
|
|
251
|
+
const setLogger = (logger, optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }) => {
|
|
252
|
+
var _a, _b, _c;
|
|
253
|
+
if (logger === self2) {
|
|
254
|
+
const err = new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");
|
|
255
|
+
self2.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message);
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
if (typeof optionsOrLogLevel === "number") {
|
|
259
|
+
optionsOrLogLevel = {
|
|
260
|
+
logLevel: optionsOrLogLevel
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
const oldLogger = getGlobal("diag");
|
|
264
|
+
const newLogger = createLogLevelDiagLogger((_b = optionsOrLogLevel.logLevel) !== null && _b !== void 0 ? _b : DiagLogLevel.INFO, logger);
|
|
265
|
+
if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
|
|
266
|
+
const stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : "<failed to generate stacktrace>";
|
|
267
|
+
oldLogger.warn(`Current logger will be overwritten from ${stack}`);
|
|
268
|
+
newLogger.warn(`Current logger will overwrite one already registered from ${stack}`);
|
|
269
|
+
}
|
|
270
|
+
return registerGlobal("diag", newLogger, self2, true);
|
|
271
|
+
};
|
|
272
|
+
self2.setLogger = setLogger;
|
|
273
|
+
self2.disable = () => {
|
|
274
|
+
unregisterGlobal(API_NAME, self2);
|
|
275
|
+
};
|
|
276
|
+
self2.createComponentLogger = (options) => {
|
|
277
|
+
return new DiagComponentLogger(options);
|
|
278
|
+
};
|
|
279
|
+
self2.verbose = _logProxy("verbose");
|
|
280
|
+
self2.debug = _logProxy("debug");
|
|
281
|
+
self2.info = _logProxy("info");
|
|
282
|
+
self2.warn = _logProxy("warn");
|
|
283
|
+
self2.error = _logProxy("error");
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js
|
|
288
|
+
var NoopMeter = class {
|
|
289
|
+
constructor() {
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* @see {@link Meter.createGauge}
|
|
293
|
+
*/
|
|
294
|
+
createGauge(_name, _options) {
|
|
295
|
+
return NOOP_GAUGE_METRIC;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* @see {@link Meter.createHistogram}
|
|
299
|
+
*/
|
|
300
|
+
createHistogram(_name, _options) {
|
|
301
|
+
return NOOP_HISTOGRAM_METRIC;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* @see {@link Meter.createCounter}
|
|
305
|
+
*/
|
|
306
|
+
createCounter(_name, _options) {
|
|
307
|
+
return NOOP_COUNTER_METRIC;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* @see {@link Meter.createUpDownCounter}
|
|
311
|
+
*/
|
|
312
|
+
createUpDownCounter(_name, _options) {
|
|
313
|
+
return NOOP_UP_DOWN_COUNTER_METRIC;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* @see {@link Meter.createObservableGauge}
|
|
317
|
+
*/
|
|
318
|
+
createObservableGauge(_name, _options) {
|
|
319
|
+
return NOOP_OBSERVABLE_GAUGE_METRIC;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* @see {@link Meter.createObservableCounter}
|
|
323
|
+
*/
|
|
324
|
+
createObservableCounter(_name, _options) {
|
|
325
|
+
return NOOP_OBSERVABLE_COUNTER_METRIC;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* @see {@link Meter.createObservableUpDownCounter}
|
|
329
|
+
*/
|
|
330
|
+
createObservableUpDownCounter(_name, _options) {
|
|
331
|
+
return NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* @see {@link Meter.addBatchObservableCallback}
|
|
335
|
+
*/
|
|
336
|
+
addBatchObservableCallback(_callback, _observables) {
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* @see {@link Meter.removeBatchObservableCallback}
|
|
340
|
+
*/
|
|
341
|
+
removeBatchObservableCallback(_callback) {
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
var NoopMetric = class {
|
|
345
|
+
};
|
|
346
|
+
var NoopCounterMetric = class extends NoopMetric {
|
|
347
|
+
add(_value, _attributes) {
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
var NoopUpDownCounterMetric = class extends NoopMetric {
|
|
351
|
+
add(_value, _attributes) {
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
var NoopGaugeMetric = class extends NoopMetric {
|
|
355
|
+
record(_value, _attributes) {
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
var NoopHistogramMetric = class extends NoopMetric {
|
|
359
|
+
record(_value, _attributes) {
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
var NoopObservableMetric = class {
|
|
363
|
+
addCallback(_callback) {
|
|
364
|
+
}
|
|
365
|
+
removeCallback(_callback) {
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
var NoopObservableCounterMetric = class extends NoopObservableMetric {
|
|
369
|
+
};
|
|
370
|
+
var NoopObservableGaugeMetric = class extends NoopObservableMetric {
|
|
371
|
+
};
|
|
372
|
+
var NoopObservableUpDownCounterMetric = class extends NoopObservableMetric {
|
|
373
|
+
};
|
|
374
|
+
var NOOP_METER = new NoopMeter();
|
|
375
|
+
var NOOP_COUNTER_METRIC = new NoopCounterMetric();
|
|
376
|
+
var NOOP_GAUGE_METRIC = new NoopGaugeMetric();
|
|
377
|
+
var NOOP_HISTOGRAM_METRIC = new NoopHistogramMetric();
|
|
378
|
+
var NOOP_UP_DOWN_COUNTER_METRIC = new NoopUpDownCounterMetric();
|
|
379
|
+
var NOOP_OBSERVABLE_COUNTER_METRIC = new NoopObservableCounterMetric();
|
|
380
|
+
var NOOP_OBSERVABLE_GAUGE_METRIC = new NoopObservableGaugeMetric();
|
|
381
|
+
var NOOP_OBSERVABLE_UP_DOWN_COUNTER_METRIC = new NoopObservableUpDownCounterMetric();
|
|
382
|
+
|
|
383
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js
|
|
384
|
+
var NoopMeterProvider = class {
|
|
385
|
+
getMeter(_name, _version, _options) {
|
|
386
|
+
return NOOP_METER;
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
var NOOP_METER_PROVIDER = new NoopMeterProvider();
|
|
390
|
+
|
|
391
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/api/metrics.js
|
|
392
|
+
var API_NAME2 = "metrics";
|
|
393
|
+
var MetricsAPI = class _MetricsAPI {
|
|
394
|
+
/** Empty private constructor prevents end users from constructing a new instance of the API */
|
|
395
|
+
constructor() {
|
|
396
|
+
}
|
|
397
|
+
/** Get the singleton instance of the Metrics API */
|
|
398
|
+
static getInstance() {
|
|
399
|
+
if (!this._instance) {
|
|
400
|
+
this._instance = new _MetricsAPI();
|
|
401
|
+
}
|
|
402
|
+
return this._instance;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Set the current global meter provider.
|
|
406
|
+
* Returns true if the meter provider was successfully registered, else false.
|
|
407
|
+
*/
|
|
408
|
+
setGlobalMeterProvider(provider) {
|
|
409
|
+
return registerGlobal(API_NAME2, provider, DiagAPI.instance());
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Returns the global meter provider.
|
|
413
|
+
*/
|
|
414
|
+
getMeterProvider() {
|
|
415
|
+
return getGlobal(API_NAME2) || NOOP_METER_PROVIDER;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Returns a meter from the global meter provider.
|
|
419
|
+
*/
|
|
420
|
+
getMeter(name, version, options) {
|
|
421
|
+
return this.getMeterProvider().getMeter(name, version, options);
|
|
422
|
+
}
|
|
423
|
+
/** Remove the global meter provider */
|
|
424
|
+
disable() {
|
|
425
|
+
unregisterGlobal(API_NAME2, DiagAPI.instance());
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
// ../../node_modules/.pnpm/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/esm/metrics-api.js
|
|
430
|
+
var metrics = MetricsAPI.getInstance();
|
|
431
|
+
|
|
432
|
+
// src/economy/otel.ts
|
|
433
|
+
var METER_NAME = "@nekzus/liop";
|
|
434
|
+
var METER_VERSION = "1.2.0-alpha.9";
|
|
435
|
+
var TOKEN_USAGE_BUCKETS = [
|
|
436
|
+
1,
|
|
437
|
+
4,
|
|
438
|
+
16,
|
|
439
|
+
64,
|
|
440
|
+
256,
|
|
441
|
+
1024,
|
|
442
|
+
4096,
|
|
443
|
+
16384,
|
|
444
|
+
65536,
|
|
445
|
+
262144,
|
|
446
|
+
1048576,
|
|
447
|
+
4194304,
|
|
448
|
+
16777216,
|
|
449
|
+
67108864
|
|
450
|
+
];
|
|
451
|
+
var DURATION_BUCKETS = [
|
|
452
|
+
0.01,
|
|
453
|
+
0.02,
|
|
454
|
+
0.04,
|
|
455
|
+
0.08,
|
|
456
|
+
0.16,
|
|
457
|
+
0.32,
|
|
458
|
+
0.64,
|
|
459
|
+
1.28,
|
|
460
|
+
2.56,
|
|
461
|
+
5.12,
|
|
462
|
+
10.24,
|
|
463
|
+
20.48,
|
|
464
|
+
40.96,
|
|
465
|
+
81.92
|
|
466
|
+
];
|
|
467
|
+
var LiopOTelBridge = class {
|
|
468
|
+
tokenUsage;
|
|
469
|
+
operationDuration;
|
|
470
|
+
active = false;
|
|
471
|
+
constructor() {
|
|
472
|
+
try {
|
|
473
|
+
const meter = metrics.getMeter(METER_NAME, METER_VERSION);
|
|
474
|
+
this.tokenUsage = meter.createHistogram("gen_ai.client.token.usage", {
|
|
475
|
+
description: "Number of tokens used in LIOP Logic-on-Origin operations",
|
|
476
|
+
unit: "{token}",
|
|
477
|
+
advice: { explicitBucketBoundaries: TOKEN_USAGE_BUCKETS }
|
|
478
|
+
});
|
|
479
|
+
this.operationDuration = meter.createHistogram(
|
|
480
|
+
"gen_ai.client.operation.duration",
|
|
481
|
+
{
|
|
482
|
+
description: "Duration of LIOP operations",
|
|
483
|
+
unit: "s",
|
|
484
|
+
advice: { explicitBucketBoundaries: DURATION_BUCKETS }
|
|
485
|
+
}
|
|
486
|
+
);
|
|
487
|
+
this.active = true;
|
|
488
|
+
log.debug("[LIOP-OTel] gen_ai.* metrics bridge initialized");
|
|
489
|
+
} catch (err) {
|
|
490
|
+
log.debug(
|
|
491
|
+
`[LIOP-OTel] Bridge disabled: ${err instanceof Error ? err.message : String(err)}`
|
|
492
|
+
);
|
|
493
|
+
const noopHistogram = {
|
|
494
|
+
record: () => {
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
this.tokenUsage = noopHistogram;
|
|
498
|
+
this.operationDuration = noopHistogram;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Record token usage with gen_ai.* standard attributes.
|
|
503
|
+
*
|
|
504
|
+
* @param tokens - Number of tokens consumed
|
|
505
|
+
* @param tokenType - "input" or "output" (gen_ai.token.type)
|
|
506
|
+
* @param operationName - gen_ai.operation.name (e.g., "execute_tool", "chat")
|
|
507
|
+
* @param toolName - Optional LIOP-specific tool name for attribution
|
|
508
|
+
*/
|
|
509
|
+
recordTokens(tokens, tokenType, operationName, toolName) {
|
|
510
|
+
this.tokenUsage.record(tokens, {
|
|
511
|
+
"gen_ai.system": "liop",
|
|
512
|
+
"gen_ai.operation.name": operationName,
|
|
513
|
+
"gen_ai.token.type": tokenType,
|
|
514
|
+
"gen_ai.request.model": "liop-mesh",
|
|
515
|
+
...toolName ? { "liop.tool.name": toolName } : {}
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Record operation duration with gen_ai.* standard attributes.
|
|
520
|
+
*
|
|
521
|
+
* @param durationMs - Duration in milliseconds (converted to seconds for OTel)
|
|
522
|
+
* @param operationName - gen_ai.operation.name
|
|
523
|
+
* @param error - Optional error type string if the operation failed
|
|
524
|
+
*/
|
|
525
|
+
recordDuration(durationMs, operationName, error) {
|
|
526
|
+
this.operationDuration.record(durationMs / 1e3, {
|
|
527
|
+
"gen_ai.system": "liop",
|
|
528
|
+
"gen_ai.operation.name": operationName,
|
|
529
|
+
...error ? { "error.type": error } : {}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
/** Whether the OTel bridge is actively connected to a MeterProvider */
|
|
533
|
+
isActive() {
|
|
534
|
+
return this.active;
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
// src/economy/telemetry.ts
|
|
539
|
+
var OTEL_OPERATION_MAP = {
|
|
540
|
+
tools_list: "chat",
|
|
541
|
+
tool_call: "execute_tool",
|
|
542
|
+
resource_read: "chat",
|
|
543
|
+
resource_list: "chat",
|
|
544
|
+
prompt_get: "chat",
|
|
545
|
+
prompt_list: "chat",
|
|
546
|
+
diagnostic: "chat"
|
|
547
|
+
};
|
|
548
|
+
var TokenTelemetryEngine = class _TokenTelemetryEngine {
|
|
549
|
+
static instance = null;
|
|
550
|
+
operations = [];
|
|
551
|
+
sessionId;
|
|
552
|
+
startedAt;
|
|
553
|
+
estimator;
|
|
554
|
+
otelBridge;
|
|
555
|
+
constructor() {
|
|
556
|
+
this.sessionId = crypto.randomUUID();
|
|
557
|
+
this.startedAt = Date.now();
|
|
558
|
+
this.estimator = createSyncTokenEstimator();
|
|
559
|
+
this.otelBridge = new LiopOTelBridge();
|
|
560
|
+
this.initRealEstimator();
|
|
561
|
+
}
|
|
562
|
+
/** Async upgrade from heuristic to real BPE tokenizer */
|
|
563
|
+
initRealEstimator() {
|
|
564
|
+
createTokenEstimator().then((real) => {
|
|
565
|
+
this.estimator = real;
|
|
566
|
+
}).catch(() => {
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
static getInstance() {
|
|
570
|
+
if (!_TokenTelemetryEngine.instance) {
|
|
571
|
+
_TokenTelemetryEngine.instance = new _TokenTelemetryEngine();
|
|
572
|
+
}
|
|
573
|
+
return _TokenTelemetryEngine.instance;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Count tokens in a string using the active estimator.
|
|
577
|
+
* Delegates to o200k_base BPE tokenizer (or heuristic fallback).
|
|
578
|
+
*/
|
|
579
|
+
countTokens(content) {
|
|
580
|
+
try {
|
|
581
|
+
return this.estimator.countTokens(content);
|
|
582
|
+
} catch {
|
|
583
|
+
return Math.ceil(content.length / 4);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Record a single MCP operation's token footprint.
|
|
588
|
+
* Emits both internal metrics and OTel gen_ai.* histograms.
|
|
589
|
+
*/
|
|
590
|
+
record(metric) {
|
|
591
|
+
const fullMetric = {
|
|
592
|
+
...metric,
|
|
593
|
+
timestamp: Date.now()
|
|
594
|
+
};
|
|
595
|
+
this.operations.push(fullMetric);
|
|
596
|
+
try {
|
|
597
|
+
const otelOp = OTEL_OPERATION_MAP[metric.type] || "chat";
|
|
598
|
+
if (metric.estimatedInputTokens > 0) {
|
|
599
|
+
this.otelBridge.recordTokens(
|
|
600
|
+
metric.estimatedInputTokens,
|
|
601
|
+
"input",
|
|
602
|
+
otelOp,
|
|
603
|
+
metric.toolName
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
if (metric.estimatedOutputTokens > 0) {
|
|
607
|
+
this.otelBridge.recordTokens(
|
|
608
|
+
metric.estimatedOutputTokens,
|
|
609
|
+
"output",
|
|
610
|
+
otelOp,
|
|
611
|
+
metric.toolName
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
if (metric.durationMs !== void 0) {
|
|
615
|
+
this.otelBridge.recordDuration(metric.durationMs, otelOp);
|
|
616
|
+
}
|
|
617
|
+
} catch {
|
|
618
|
+
}
|
|
619
|
+
try {
|
|
620
|
+
const promLabels = {
|
|
621
|
+
type: metric.type,
|
|
622
|
+
method: metric.method,
|
|
623
|
+
tool: metric.toolName || "none"
|
|
624
|
+
};
|
|
625
|
+
if (metric.estimatedInputTokens > 0) {
|
|
626
|
+
tokensInputTotal.inc(promLabels, metric.estimatedInputTokens);
|
|
627
|
+
}
|
|
628
|
+
if (metric.estimatedOutputTokens > 0) {
|
|
629
|
+
tokensOutputTotal.inc(promLabels, metric.estimatedOutputTokens);
|
|
630
|
+
}
|
|
631
|
+
if (metric.originDatasetTokens !== void 0 && metric.originDatasetTokens > metric.estimatedOutputTokens) {
|
|
632
|
+
const actualSaved = metric.originDatasetTokens - metric.estimatedOutputTokens;
|
|
633
|
+
tokensSavedTotal.inc({ tool: metric.toolName || "none" }, actualSaved);
|
|
634
|
+
}
|
|
635
|
+
if (metric.durationMs !== void 0 && metric.durationMs >= 0) {
|
|
636
|
+
operationDurationMs.observe(promLabels, metric.durationMs);
|
|
637
|
+
}
|
|
638
|
+
} catch {
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* @deprecated Use countTokens() instead. Kept for backward compatibility.
|
|
643
|
+
*/
|
|
644
|
+
estimateTokens(content) {
|
|
645
|
+
return this.countTokens(content);
|
|
646
|
+
}
|
|
647
|
+
/** Generate the full session report */
|
|
648
|
+
getReport() {
|
|
649
|
+
return {
|
|
650
|
+
sessionId: this.sessionId,
|
|
651
|
+
operations: [...this.operations],
|
|
652
|
+
totalInputTokens: this.operations.reduce(
|
|
653
|
+
(sum, op) => sum + op.estimatedInputTokens,
|
|
654
|
+
0
|
|
655
|
+
),
|
|
656
|
+
totalOutputTokens: this.operations.reduce(
|
|
657
|
+
(sum, op) => sum + op.estimatedOutputTokens,
|
|
658
|
+
0
|
|
659
|
+
),
|
|
660
|
+
estimatorName: this.estimator.name,
|
|
661
|
+
sessionUptimeMs: Date.now() - this.startedAt
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
/** Get per-tool token breakdown for diagnostic display */
|
|
665
|
+
getPerToolReport() {
|
|
666
|
+
const breakdown = /* @__PURE__ */ new Map();
|
|
667
|
+
for (const op of this.operations) {
|
|
668
|
+
const key = op.toolName || op.method;
|
|
669
|
+
const existing = breakdown.get(key) || {
|
|
670
|
+
input: 0,
|
|
671
|
+
output: 0,
|
|
672
|
+
calls: 0,
|
|
673
|
+
avgDurationMs: 0
|
|
674
|
+
};
|
|
675
|
+
const totalDuration = existing.avgDurationMs * existing.calls + (op.durationMs || 0);
|
|
676
|
+
const newCalls = existing.calls + 1;
|
|
677
|
+
breakdown.set(key, {
|
|
678
|
+
input: existing.input + op.estimatedInputTokens,
|
|
679
|
+
output: existing.output + op.estimatedOutputTokens,
|
|
680
|
+
calls: newCalls,
|
|
681
|
+
avgDurationMs: newCalls > 0 ? totalDuration / newCalls : 0
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
return breakdown;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Format a rich, human-readable summary block for LiopMeshStatus diagnostic.
|
|
688
|
+
* Returns empty string when no operations have been recorded.
|
|
689
|
+
*/
|
|
690
|
+
formatStatusBlock() {
|
|
691
|
+
const report = this.getReport();
|
|
692
|
+
if (report.operations.length === 0) return "";
|
|
693
|
+
const uptimeStr = this.formatUptime(report.sessionUptimeMs);
|
|
694
|
+
const totalCombined = report.totalInputTokens + report.totalOutputTokens;
|
|
695
|
+
const byType = /* @__PURE__ */ new Map();
|
|
696
|
+
for (const op of report.operations) {
|
|
697
|
+
const key = op.type;
|
|
698
|
+
const existing = byType.get(key) || {
|
|
699
|
+
count: 0,
|
|
700
|
+
input: 0,
|
|
701
|
+
output: 0
|
|
702
|
+
};
|
|
703
|
+
byType.set(key, {
|
|
704
|
+
count: existing.count + 1,
|
|
705
|
+
input: existing.input + op.estimatedInputTokens,
|
|
706
|
+
output: existing.output + op.estimatedOutputTokens
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
const typeEntries = Array.from(byType.entries());
|
|
710
|
+
const typeLines = typeEntries.map(([type, data], idx) => {
|
|
711
|
+
const prefix = idx === typeEntries.length - 1 ? "\u2502 \u2514\u2500" : "\u2502 \u251C\u2500";
|
|
712
|
+
const outputPart = data.output > 0 ? ` / ${data.output.toLocaleString()} out` : "";
|
|
713
|
+
return `${prefix} ${type} \xD7${data.count} \u2192 ${data.input.toLocaleString()} in${outputPart}`;
|
|
714
|
+
});
|
|
715
|
+
const toolReport = this.getPerToolReport();
|
|
716
|
+
const toolEntries = Array.from(toolReport.entries()).filter(
|
|
717
|
+
([key]) => key !== "tools/list" && key !== "LiopMeshStatus"
|
|
718
|
+
);
|
|
719
|
+
const toolLines = [];
|
|
720
|
+
if (toolEntries.length > 0) {
|
|
721
|
+
toolLines.push("\u251C\u2500 By Tool:");
|
|
722
|
+
toolEntries.forEach(([name, data], idx) => {
|
|
723
|
+
const prefix = idx === toolEntries.length - 1 ? "\u2502 \u2514\u2500" : "\u2502 \u251C\u2500";
|
|
724
|
+
const outputPart = data.output > 0 ? ` / ${data.output.toLocaleString()} out` : "";
|
|
725
|
+
const durationPart = data.avgDurationMs > 0 ? ` ~${Math.round(data.avgDurationMs)}ms` : "";
|
|
726
|
+
toolLines.push(
|
|
727
|
+
`${prefix} ${name}: ${data.input.toLocaleString()} in${outputPart} (\xD7${data.calls})${durationPart}`
|
|
728
|
+
);
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
const timedOps = report.operations.filter(
|
|
732
|
+
(op) => op.durationMs !== void 0
|
|
733
|
+
);
|
|
734
|
+
const avgLatency = timedOps.length > 0 ? Math.round(
|
|
735
|
+
timedOps.reduce((sum, op) => sum + (op.durationMs || 0), 0) / timedOps.length
|
|
736
|
+
) : 0;
|
|
737
|
+
const otelStatus = this.otelBridge.isActive() ? "gen_ai.client.token.usage \u2192 active" : "disabled";
|
|
738
|
+
const lines = [
|
|
739
|
+
"\nToken Economy:",
|
|
740
|
+
`\u251C\u2500 Session: ${report.sessionId.slice(0, 8)} (${uptimeStr})`,
|
|
741
|
+
`\u251C\u2500 Estimator: ${report.estimatorName}`,
|
|
742
|
+
`\u251C\u2500 Operations: ${report.operations.length}`,
|
|
743
|
+
...typeLines,
|
|
744
|
+
`\u251C\u2500 Total: ${report.totalInputTokens.toLocaleString()} in / ${report.totalOutputTokens.toLocaleString()} out (${totalCombined.toLocaleString()} combined)`,
|
|
745
|
+
...toolLines,
|
|
746
|
+
...avgLatency > 0 ? [`\u251C\u2500 Avg Latency: ${avgLatency}ms`] : [],
|
|
747
|
+
`\u2514\u2500 OTel: ${otelStatus}`
|
|
748
|
+
];
|
|
749
|
+
return lines.join("\n");
|
|
750
|
+
}
|
|
751
|
+
/** Format milliseconds into human-readable uptime string */
|
|
752
|
+
formatUptime(ms) {
|
|
753
|
+
const seconds = Math.floor(ms / 1e3);
|
|
754
|
+
if (seconds < 60) return `${seconds}s`;
|
|
755
|
+
const minutes = Math.floor(seconds / 60);
|
|
756
|
+
const remainingSeconds = seconds % 60;
|
|
757
|
+
if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;
|
|
758
|
+
const hours = Math.floor(minutes / 60);
|
|
759
|
+
const remainingMinutes = minutes % 60;
|
|
760
|
+
return `${hours}h ${remainingMinutes}m`;
|
|
761
|
+
}
|
|
762
|
+
/** Reset all recorded metrics (used in tests) */
|
|
763
|
+
reset() {
|
|
764
|
+
this.operations = [];
|
|
765
|
+
}
|
|
766
|
+
/** Destroy the singleton (used in tests to guarantee isolation) */
|
|
767
|
+
static destroy() {
|
|
768
|
+
_TokenTelemetryEngine.instance = null;
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
var isTlsEnforced = () => process.env.NODE_ENV === "production" || process.env.LIOP_ENFORCE_TLS === "true";
|
|
772
|
+
var isTlsWarningSuppressed = (tls) => tls?.insecure === true || tls?.suppressWarning === true || process.env.LIOP_SUPPRESS_TLS_WARNING === "true";
|
|
773
|
+
var hasWarnedInsecureServer = false;
|
|
774
|
+
var hasWarnedInsecureChannel = false;
|
|
775
|
+
function createServerCredentials(tls) {
|
|
776
|
+
if (tls?.mutualTls && !tls.rootCert && !tls.certManager?.getRootCert()) {
|
|
777
|
+
throw new Error(
|
|
778
|
+
"[LIOP-TLS] FATAL: Mutual TLS (mTLS) enabled but no root CA certificate (rootCert) provided to verify client certificates."
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
if (tls?.certManager) {
|
|
782
|
+
try {
|
|
783
|
+
const certChain = tls.certManager.getCertChain();
|
|
784
|
+
const privateKey = tls.certManager.getPrivateKey();
|
|
785
|
+
const rootCert = tls.certManager.getRootCert();
|
|
786
|
+
if (tls.mutualTls && !rootCert) {
|
|
787
|
+
throw new Error(
|
|
788
|
+
"[LIOP-TLS] FATAL: Mutual TLS (mTLS) enabled but CertManager has no root CA certificate loaded."
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
return grpc.ServerCredentials.createSsl(
|
|
792
|
+
rootCert,
|
|
793
|
+
[{ cert_chain: certChain, private_key: privateKey }],
|
|
794
|
+
Boolean(tls.mutualTls)
|
|
795
|
+
);
|
|
796
|
+
} catch (error) {
|
|
797
|
+
if (isTlsEnforced()) {
|
|
798
|
+
throw new Error(
|
|
799
|
+
`[LIOP-TLS] FATAL: CertManager server credential creation failed in enforced mode: ${error}`
|
|
800
|
+
);
|
|
801
|
+
}
|
|
802
|
+
log.warn(
|
|
803
|
+
`[LIOP-TLS] CertManager failed, falling back to insecure: ${error}`
|
|
804
|
+
);
|
|
805
|
+
return grpc.ServerCredentials.createInsecure();
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
if (!tls?.certChain || !tls?.privateKey) {
|
|
809
|
+
if (isTlsEnforced()) {
|
|
810
|
+
throw new Error(
|
|
811
|
+
"[LIOP-TLS] FATAL: TLS certificates required in production or when LIOP_ENFORCE_TLS=true."
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
if (!isTlsWarningSuppressed(tls) && !hasWarnedInsecureServer) {
|
|
815
|
+
hasWarnedInsecureServer = true;
|
|
816
|
+
log.debug(
|
|
817
|
+
"[LIOP-TLS] No TLS certificates configured \u2014 using insecure server credentials"
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
return grpc.ServerCredentials.createInsecure();
|
|
821
|
+
}
|
|
822
|
+
try {
|
|
823
|
+
const rootCert = tls.rootCert ? fs.readFileSync(tls.rootCert) : null;
|
|
824
|
+
const certChain = fs.readFileSync(tls.certChain);
|
|
825
|
+
const privateKey = fs.readFileSync(tls.privateKey);
|
|
826
|
+
if (tls.mutualTls && !rootCert) {
|
|
827
|
+
throw new Error(
|
|
828
|
+
"[LIOP-TLS] FATAL: Mutual TLS (mTLS) enabled but no root CA certificate (rootCert) provided to verify client certificates."
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
return grpc.ServerCredentials.createSsl(
|
|
832
|
+
rootCert,
|
|
833
|
+
[{ cert_chain: certChain, private_key: privateKey }],
|
|
834
|
+
Boolean(tls.mutualTls)
|
|
835
|
+
);
|
|
836
|
+
} catch (error) {
|
|
837
|
+
if (isTlsEnforced()) {
|
|
838
|
+
throw new Error(
|
|
839
|
+
`[LIOP-TLS] FATAL: Server certificate loading failed in production or enforced mode. Refusing insecure fallback to prevent MITM/eavesdropping: ${error}`
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
log.warn(
|
|
843
|
+
`[LIOP-TLS] Server certificate loading failed, falling back to insecure (dev mode): ${error}`
|
|
844
|
+
);
|
|
845
|
+
return grpc.ServerCredentials.createInsecure();
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
function createChannelCredentials(tls) {
|
|
849
|
+
if (tls?.certManager) {
|
|
850
|
+
try {
|
|
851
|
+
const rootCert = tls.certManager.getRootCert();
|
|
852
|
+
if (!rootCert) {
|
|
853
|
+
throw new Error(
|
|
854
|
+
"[LIOP-TLS] FATAL: Channel TLS requires a root CA certificate in CertManager."
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
const certChain = tls.certManager.getCertChain();
|
|
858
|
+
const privateKey = tls.certManager.getPrivateKey();
|
|
859
|
+
return grpc.credentials.createSsl(rootCert, privateKey, certChain);
|
|
860
|
+
} catch (error) {
|
|
861
|
+
if (isTlsEnforced()) {
|
|
862
|
+
throw new Error(
|
|
863
|
+
`[LIOP-TLS] FATAL: Channel certificate loading failed in enforced mode: ${error}`
|
|
864
|
+
);
|
|
865
|
+
}
|
|
866
|
+
log.warn(
|
|
867
|
+
`[LIOP-TLS] Channel CertManager failed, falling back to insecure: ${error}`
|
|
868
|
+
);
|
|
869
|
+
return grpc.credentials.createInsecure();
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
if (!tls?.rootCert) {
|
|
873
|
+
if (isTlsEnforced()) {
|
|
874
|
+
throw new Error(
|
|
875
|
+
"[LIOP-TLS] FATAL: TLS root certificate required in production or when LIOP_ENFORCE_TLS=true."
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
if (!isTlsWarningSuppressed(tls) && !hasWarnedInsecureChannel) {
|
|
879
|
+
hasWarnedInsecureChannel = true;
|
|
880
|
+
log.debug(
|
|
881
|
+
"[LIOP-TLS] No TLS root certificate configured \u2014 using insecure channel credentials"
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
return grpc.credentials.createInsecure();
|
|
885
|
+
}
|
|
886
|
+
try {
|
|
887
|
+
const rootCert = fs.readFileSync(tls.rootCert);
|
|
888
|
+
const certChain = tls.certChain ? fs.readFileSync(tls.certChain) : void 0;
|
|
889
|
+
const privateKey = tls.privateKey ? fs.readFileSync(tls.privateKey) : void 0;
|
|
890
|
+
return grpc.credentials.createSsl(rootCert, privateKey, certChain);
|
|
891
|
+
} catch (error) {
|
|
892
|
+
if (isTlsEnforced()) {
|
|
893
|
+
throw new Error(
|
|
894
|
+
`[LIOP-TLS] FATAL: Channel certificate loading failed in production or enforced mode. Refusing insecure fallback to prevent MITM/eavesdropping: ${error}`
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
log.warn(
|
|
898
|
+
`[LIOP-TLS] Channel certificate loading failed, falling back to insecure (dev mode): ${error}`
|
|
899
|
+
);
|
|
900
|
+
return grpc.credentials.createInsecure();
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// src/rpc/channel-options.ts
|
|
905
|
+
var GRPC_CHANNEL_OPTIONS = {
|
|
906
|
+
"grpc.keepalive_time_ms": 3e4,
|
|
907
|
+
"grpc.keepalive_timeout_ms": 1e4,
|
|
908
|
+
"grpc.keepalive_permit_without_calls": 1,
|
|
909
|
+
"grpc.max_send_message_length": -1,
|
|
910
|
+
"grpc.max_receive_message_length": -1,
|
|
911
|
+
"grpc.enable_retries": 1
|
|
912
|
+
};
|
|
913
|
+
var __filename2 = fileURLToPath(import.meta.url);
|
|
914
|
+
var __dirname2 = path.dirname(__filename2);
|
|
915
|
+
var PROD_PATHS = [
|
|
916
|
+
path.resolve(__dirname2, "./protocol/liop_core.proto"),
|
|
917
|
+
// Flat dist/ (tsup)
|
|
918
|
+
path.resolve(__dirname2, "../protocol/liop_core.proto")
|
|
919
|
+
// dist/rpc/ (tsc)
|
|
920
|
+
];
|
|
921
|
+
var DEV_PROTO_PATH = path.resolve(
|
|
922
|
+
__dirname2,
|
|
923
|
+
"../../../../protocol/proto/liop_core.proto"
|
|
924
|
+
);
|
|
925
|
+
var PROTO_PATH = PROD_PATHS.find((p) => fs.existsSync(p)) || DEV_PROTO_PATH;
|
|
926
|
+
if (!fs.existsSync(PROTO_PATH)) {
|
|
927
|
+
log.error(`[LIOP-Proto] CRITICAL: Proto file not found at ${PROTO_PATH}`);
|
|
928
|
+
}
|
|
929
|
+
var packageDefinition = protoLoader.loadSync(PROTO_PATH, {
|
|
930
|
+
keepCase: true,
|
|
931
|
+
longs: String,
|
|
932
|
+
enums: String,
|
|
933
|
+
defaults: true,
|
|
934
|
+
oneofs: true
|
|
935
|
+
});
|
|
936
|
+
var liopProto = grpc.loadPackageDefinition(packageDefinition);
|
|
937
|
+
var liopV1 = liopProto.liop.v1;
|
|
938
|
+
|
|
939
|
+
export { GRPC_CHANNEL_OPTIONS, HeuristicTokenEstimator, LiopOTelBridge, RealTokenEstimator, TokenTelemetryEngine, createChannelCredentials, createServerCredentials, createSyncTokenEstimator, createTokenEstimator, liopV1 };
|
|
940
|
+
//# sourceMappingURL=chunk-JPWC6XG6.js.map
|
|
941
|
+
//# sourceMappingURL=chunk-JPWC6XG6.js.map
|