@nekzus/liop 2.4.0-alpha.7 → 2.4.0-alpha.8

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.
Files changed (92) hide show
  1. package/NOTICE +19 -0
  2. package/README.md +36 -17
  3. package/dist/bin/agent.js +674 -82
  4. package/dist/bin/agent.js.map +1 -1
  5. package/dist/bridge.d.ts +2 -2
  6. package/dist/bridge.js +3 -3
  7. package/dist/{chunk-T5IUZF47.js → chunk-3L2O2XKG.js} +12 -5
  8. package/dist/chunk-3L2O2XKG.js.map +1 -0
  9. package/dist/{chunk-SONUORBT.js → chunk-7BSCUYUE.js} +2 -2
  10. package/dist/chunk-7BSCUYUE.js.map +1 -0
  11. package/dist/{chunk-QLCOEP5J.js → chunk-7PITYWOV.js} +2 -2
  12. package/dist/chunk-7PITYWOV.js.map +1 -0
  13. package/dist/{chunk-74CISO2I.js → chunk-7RXOIDXP.js} +28 -4
  14. package/dist/chunk-7RXOIDXP.js.map +1 -0
  15. package/dist/{chunk-GA3Q2S7O.js → chunk-BOISQ45Z.js} +5 -5
  16. package/dist/chunk-BOISQ45Z.js.map +1 -0
  17. package/dist/{chunk-547TYL27.js → chunk-DZ2FQGJD.js} +26 -1423
  18. package/dist/chunk-DZ2FQGJD.js.map +1 -0
  19. package/dist/{chunk-PYKRQAER.js → chunk-EG46XMJT.js} +2 -2
  20. package/dist/chunk-EG46XMJT.js.map +1 -0
  21. package/dist/chunk-ESRXG36Y.js +115 -0
  22. package/dist/chunk-ESRXG36Y.js.map +1 -0
  23. package/dist/chunk-FTF6AMF6.js +3 -0
  24. package/dist/{chunk-RWRRBYG4.js.map → chunk-FTF6AMF6.js.map} +1 -1
  25. package/dist/{chunk-72MNYFR6.js → chunk-HA6YZ42O.js} +2 -2
  26. package/dist/chunk-HA6YZ42O.js.map +1 -0
  27. package/dist/{chunk-WCCGE4QR.js → chunk-HD2N3IJX.js} +144 -30
  28. package/dist/chunk-HD2N3IJX.js.map +1 -0
  29. package/dist/{chunk-OUUTDSOW.js → chunk-IK7CGWAZ.js} +3 -3
  30. package/dist/chunk-IK7CGWAZ.js.map +1 -0
  31. package/dist/chunk-L6J72C5X.js +1477 -0
  32. package/dist/chunk-L6J72C5X.js.map +1 -0
  33. package/dist/{chunk-U5BZ66VX.js → chunk-PAICJCKJ.js} +60 -175
  34. package/dist/chunk-PAICJCKJ.js.map +1 -0
  35. package/dist/{chunk-32ADSAJS.js → chunk-PEN3KFLF.js} +14 -4
  36. package/dist/chunk-PEN3KFLF.js.map +1 -0
  37. package/dist/{chunk-CRZBVFDV.js → chunk-T7R5HUFD.js} +225 -66
  38. package/dist/chunk-T7R5HUFD.js.map +1 -0
  39. package/dist/{chunk-WSW6YJNY.js → chunk-TKRX6CFI.js} +3 -3
  40. package/dist/chunk-TKRX6CFI.js.map +1 -0
  41. package/dist/chunk-UCVP3XAL.js +279 -0
  42. package/dist/chunk-UCVP3XAL.js.map +1 -0
  43. package/dist/chunk-VH4K4U45.js +180 -0
  44. package/dist/chunk-VH4K4U45.js.map +1 -0
  45. package/dist/{chunk-JIJPZFR2.js → chunk-Y62GORQF.js} +2 -2
  46. package/dist/chunk-Y62GORQF.js.map +1 -0
  47. package/dist/chunk-ZP3VVXOI.js +66 -0
  48. package/dist/chunk-ZP3VVXOI.js.map +1 -0
  49. package/dist/client.d.ts +2 -2
  50. package/dist/client.js +11 -8
  51. package/dist/gateway.d.ts +3 -3
  52. package/dist/gateway.js +11 -9
  53. package/dist/{hybrid-CF__0YnC.d.ts → hybrid-CrKB50nh.d.ts} +2 -2
  54. package/dist/{index-cMV0_yD9.d.ts → index-CX43dvMs.d.ts} +2 -32
  55. package/dist/{index-BW95kAL4.d.ts → index-DoW2gzBZ.d.ts} +3 -21
  56. package/dist/index.d.ts +170 -46
  57. package/dist/index.js +20 -15
  58. package/dist/index.js.map +1 -1
  59. package/dist/kyber-CGOA7Q6A.js +3 -0
  60. package/dist/{kyber-3ULIJSE3.js.map → kyber-CGOA7Q6A.js.map} +1 -1
  61. package/dist/mesh.d.ts +27 -143
  62. package/dist/mesh.js +4 -3
  63. package/dist/node-B0b2vUFS.d.ts +164 -0
  64. package/dist/protocol/liop_core.proto +3 -0
  65. package/dist/server.d.ts +2 -2
  66. package/dist/server.js +7 -6
  67. package/dist/types.js +1 -1
  68. package/dist/verifier-HRFXBKT5.js +6 -0
  69. package/dist/{verifier-3FAKCFNN.js.map → verifier-HRFXBKT5.js.map} +1 -1
  70. package/dist/workers/logic-execution.js +3 -3
  71. package/dist/workers/logic-execution.js.map +1 -1
  72. package/dist/workers/zk-verifier.js +1 -1
  73. package/dist/workers/zk-verifier.js.map +1 -1
  74. package/package.json +8 -2
  75. package/dist/chunk-32ADSAJS.js.map +0 -1
  76. package/dist/chunk-547TYL27.js.map +0 -1
  77. package/dist/chunk-72MNYFR6.js.map +0 -1
  78. package/dist/chunk-74CISO2I.js.map +0 -1
  79. package/dist/chunk-CRZBVFDV.js.map +0 -1
  80. package/dist/chunk-GA3Q2S7O.js.map +0 -1
  81. package/dist/chunk-JIJPZFR2.js.map +0 -1
  82. package/dist/chunk-OUUTDSOW.js.map +0 -1
  83. package/dist/chunk-PYKRQAER.js.map +0 -1
  84. package/dist/chunk-QLCOEP5J.js.map +0 -1
  85. package/dist/chunk-RWRRBYG4.js +0 -3
  86. package/dist/chunk-SONUORBT.js.map +0 -1
  87. package/dist/chunk-T5IUZF47.js.map +0 -1
  88. package/dist/chunk-U5BZ66VX.js.map +0 -1
  89. package/dist/chunk-WCCGE4QR.js.map +0 -1
  90. package/dist/chunk-WSW6YJNY.js.map +0 -1
  91. package/dist/kyber-3ULIJSE3.js +0 -3
  92. package/dist/verifier-3FAKCFNN.js +0 -5
@@ -1,5 +1,6 @@
1
- import { deriveLogicImageDigest } from './chunk-OUUTDSOW.js';
2
- import { log } from './chunk-72MNYFR6.js';
1
+ import { deriveLogicImageDigest } from './chunk-IK7CGWAZ.js';
2
+ import { zkVerificationDurationMs } from './chunk-PAICJCKJ.js';
3
+ import { log } from './chunk-HA6YZ42O.js';
3
4
  import * as fs from 'fs';
4
5
  import { createRequire } from 'module';
5
6
  import path from 'path';
@@ -61,6 +62,7 @@ var LiopVerifier = class _LiopVerifier {
61
62
  async verifyZkReceipt(logicPayload, remoteImageIdHex, zkReceipt, sessionSecret, expectedOutput) {
62
63
  const pool = this.getZkPool();
63
64
  if (!pool) throw new Error("Worker pool initialization failed");
65
+ const startTime = performance.now();
64
66
  const result = await pool.run({
65
67
  action: "verify_receipt",
66
68
  logicPayload: new Uint8Array(logicPayload),
@@ -69,6 +71,14 @@ var LiopVerifier = class _LiopVerifier {
69
71
  sessionSecret: sessionSecret ? new Uint8Array(sessionSecret) : void 0,
70
72
  expectedOutput
71
73
  });
74
+ const durationMs = performance.now() - startTime;
75
+ try {
76
+ zkVerificationDurationMs.observe(
77
+ { status: result.verified ? "verified" : "failed" },
78
+ durationMs
79
+ );
80
+ } catch {
81
+ }
72
82
  if (result.verified) {
73
83
  log.info(`[LiopVerifier] ${result.message}`);
74
84
  return true;
@@ -100,5 +110,5 @@ var LiopVerifier = class _LiopVerifier {
100
110
  };
101
111
 
102
112
  export { LiopVerifier };
103
- //# sourceMappingURL=chunk-32ADSAJS.js.map
104
- //# sourceMappingURL=chunk-32ADSAJS.js.map
113
+ //# sourceMappingURL=chunk-PEN3KFLF.js.map
114
+ //# sourceMappingURL=chunk-PEN3KFLF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/crypto/verifier.ts"],"names":["__filename","__dirname"],"mappings":"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","file":"chunk-PEN3KFLF.js","sourcesContent":["// Copyright 2026 Nekzus Solutions and contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { Piscina } from \"piscina\";\nimport { zkVerificationDurationMs } from \"../observability/metrics.js\";\nimport { log } from \"../utils/logger.js\";\nimport { deriveLogicImageDigest } from \"./logic-image-id.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * LIOP Tier-0 Industrial Verifier\n *\n * This engine is responsible for the trustless verification of remote logic execution.\n * It validates both the integrity of the code (ZkImageID) and the mathematical proof\n * of its execution (ZkSeal), as well as hardware-level attestation (TEE).\n */\nexport class LiopVerifier {\n\t// Singleton Worker Pool for heavy ZK verification\n\tprivate static zkWorkerPool: Piscina | null = null;\n\n\tprivate getZkPool() {\n\t\tif (!LiopVerifier.zkWorkerPool) {\n\t\t\tconst isTS = import.meta.url.endsWith(\".ts\");\n\t\t\tconst workerExt = isTS ? \".ts\" : \".js\";\n\n\t\t\tlet execArgv: string[] = [];\n\t\t\tif (isTS) {\n\t\t\t\ttry {\n\t\t\t\t\tconst req = createRequire(import.meta.url);\n\t\t\t\t\tconst tsxPkg = req.resolve(\"tsx/package.json\");\n\t\t\t\t\tconst absoluteTsx = pathToFileURL(\n\t\t\t\t\t\tpath.join(path.dirname(tsxPkg), \"dist\", \"loader.mjs\"),\n\t\t\t\t\t).href;\n\t\t\t\t\texecArgv = [\"--import\", absoluteTsx];\n\t\t\t\t} catch (_e) {\n\t\t\t\t\texecArgv = [\"--import\", \"tsx\"];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Support both flat dist/ and original src/ structure\n\t\t\tconst workerPaths = [\n\t\t\t\tpath.resolve(__dirname, `./workers/zk-verifier${workerExt}`), // Flat dist/ (tsup)\n\t\t\t\tpath.resolve(__dirname, `../workers/zk-verifier${workerExt}`), // Original src/\n\t\t\t];\n\n\t\t\tconst workerFilename =\n\t\t\t\tworkerPaths.find((p) => fs.existsSync(p)) || workerPaths[1];\n\n\t\t\tLiopVerifier.zkWorkerPool = new Piscina({\n\t\t\t\tfilename: workerFilename,\n\t\t\t\tminThreads: 1,\n\t\t\t\tmaxThreads: 2, // Minimal footprint since verification is fast compared to generation\n\t\t\t\tidleTimeout: 30000,\n\t\t\t\texecArgv,\n\t\t\t});\n\n\t\t\t// Pre-warm the verification worker\n\t\t\tLiopVerifier.zkWorkerPool.run({ action: \"warmup\" }).catch((err) => {\n\t\t\t\tlog.debug(\n\t\t\t\t\t`[LiopVerifier] Verification pool warm-up ping failed: ${err.message}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t\treturn LiopVerifier.zkWorkerPool;\n\t}\n\n\t/**\n\t * Verifies a Zero-Knowledge Receipt from a remote LIOP node via Worker Pool.\n\t *\n\t * @param logicPayload The raw WASM or JS logic that was sent to the provider.\n\t * @param remoteImageIdHex The ImageID reported by the provider (must match our local calculation).\n\t * @param zkReceipt The mathematical proof (Seal + Journal) from the zkVM.\n\t */\n\tpublic async verifyZkReceipt(\n\t\tlogicPayload: Buffer,\n\t\tremoteImageIdHex: string,\n\t\tzkReceipt: Buffer,\n\t\tsessionSecret?: Buffer,\n\t\texpectedOutput?: unknown,\n\t): Promise<boolean> {\n\t\tconst pool = this.getZkPool();\n\t\tif (!pool) throw new Error(\"Worker pool initialization failed\");\n\t\tconst startTime = performance.now();\n\t\tconst result = await pool.run({\n\t\t\taction: \"verify_receipt\",\n\t\t\tlogicPayload: new Uint8Array(logicPayload),\n\t\t\tremoteImageIdHex,\n\t\t\tzkReceipt: new Uint8Array(zkReceipt),\n\t\t\tsessionSecret: sessionSecret ? new Uint8Array(sessionSecret) : undefined,\n\t\t\texpectedOutput,\n\t\t});\n\t\tconst durationMs = performance.now() - startTime;\n\n\t\ttry {\n\t\t\tzkVerificationDurationMs.observe(\n\t\t\t\t{ status: result.verified ? \"verified\" : \"failed\" },\n\t\t\t\tdurationMs,\n\t\t\t);\n\t\t} catch {\n\t\t\t// Metrics observation failure must never disrupt cryptographic verification\n\t\t}\n\n\t\tif (result.verified) {\n\t\t\tlog.info(`[LiopVerifier] ${result.message}`);\n\t\t\treturn true;\n\t\t}\n\n\t\tlog.error(`[LiopVerifier] FAILED: ${result.message}`);\n\t\treturn false;\n\t}\n\n\t/**\n\t * Verifies if a node is running inside an authenticated TEE (e.g. AWS Nitro).\n\t *\n\t * @param attestationReport The COSE-signed attestation document from the hardware.\n\t */\n\tpublic async verifyTeeAttestation(\n\t\tattestationReport: Buffer,\n\t): Promise<boolean> {\n\t\tif (attestationReport.length === 0) return true; // Optional in Mesh Alpha\n\n\t\ttry {\n\t\t\t// Architecture for AWS Nitro Enclaves:\n\t\t\t// 1. Decode CBOR/COSE\n\t\t\t// 2. Verify Signature against AWS Nitro Root CA\n\t\t\t// 3. Compare PCRs\n\t\t\tlog.info(\"[LiopVerifier] TEE Attestation: Not configured (no-op).\");\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tlog.error(\"[LiopVerifier] TEE Verification Failed:\", err);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Derives the ImageID of a logic payload following the LIOP v1 Standard.\n\t */\n\tpublic deriveImageId(logicPayload: Buffer): Buffer {\n\t\treturn deriveLogicImageDigest(logicPayload);\n\t}\n}\n"]}
@@ -1,9 +1,12 @@
1
- import { LiopVerifier } from './chunk-32ADSAJS.js';
2
- import { Kyber768Wrapper } from './chunk-QLCOEP5J.js';
3
- import { createChannelCredentials, liopV1, GRPC_CHANNEL_OPTIONS } from './chunk-WSW6YJNY.js';
4
- import { MCP_PROTOCOL_VERSION, MCP_LEGACY_SUPPORT_ENABLED, MCP_PROTOCOL_VERSION_LEGACY } from './chunk-PYKRQAER.js';
5
- import { MeshNode } from './chunk-74CISO2I.js';
6
- import { log } from './chunk-72MNYFR6.js';
1
+ import { TokenManager } from './chunk-ESRXG36Y.js';
2
+ import { TokenTelemetryEngine } from './chunk-DZ2FQGJD.js';
3
+ import { LiopVerifier } from './chunk-PEN3KFLF.js';
4
+ import { Kyber768Wrapper } from './chunk-7PITYWOV.js';
5
+ import { createChannelCredentials, liopV1, GRPC_CHANNEL_OPTIONS } from './chunk-TKRX6CFI.js';
6
+ import { pqcHandshakesTotal, pqcHandshakeDurationMs, zkVerificationsTotal, toolCallErrorsTotal, wireEgressBytesTotal } from './chunk-PAICJCKJ.js';
7
+ import { MCP_PROTOCOL_VERSION, MCP_LEGACY_SUPPORT_ENABLED, MCP_PROTOCOL_VERSION_LEGACY } from './chunk-EG46XMJT.js';
8
+ import { MeshNode } from './chunk-7RXOIDXP.js';
9
+ import { log } from './chunk-HA6YZ42O.js';
7
10
  import * as grpc from '@grpc/grpc-js';
8
11
  import { createDecipheriv, randomBytes, createCipheriv } from 'crypto';
9
12
 
@@ -11,6 +14,7 @@ var LiopRpcClient = class {
11
14
  // biome-ignore lint/suspicious/noExplicitAny: internal gRPC client type
12
15
  client;
13
16
  token;
17
+ lastResolvedToken;
14
18
  address;
15
19
  constructor(address, tls, token) {
16
20
  const credentials = createChannelCredentials(tls);
@@ -20,17 +24,35 @@ var LiopRpcClient = class {
20
24
  GRPC_CHANNEL_OPTIONS
21
25
  );
22
26
  this.token = token;
27
+ if (typeof token === "string") {
28
+ this.lastResolvedToken = token;
29
+ }
23
30
  this.address = address;
24
31
  }
32
+ setToken(token) {
33
+ this.token = token;
34
+ if (typeof token === "string") {
35
+ this.lastResolvedToken = token;
36
+ }
37
+ }
38
+ async resolveToken() {
39
+ if (typeof this.token === "function") {
40
+ this.lastResolvedToken = await this.token();
41
+ return this.lastResolvedToken;
42
+ }
43
+ this.lastResolvedToken = this.token;
44
+ return this.token;
45
+ }
25
46
  /**
26
47
  * Negotiates intent with the remote host.
27
48
  * Returns the ephemeral Kyber public key for payload encryption.
28
49
  */
29
50
  async negotiateIntent(request) {
51
+ const activeToken = await this.resolveToken();
30
52
  return new Promise((resolve, reject) => {
31
53
  const metadata = new grpc.Metadata();
32
- if (this.token) {
33
- metadata.add("authorization", `Bearer ${this.token}`);
54
+ if (activeToken) {
55
+ metadata.add("authorization", `Bearer ${activeToken}`);
34
56
  }
35
57
  this.client.NegotiateIntent(
36
58
  request,
@@ -51,8 +73,9 @@ var LiopRpcClient = class {
51
73
  */
52
74
  executeLogic(request) {
53
75
  const metadata = new grpc.Metadata();
54
- if (this.token) {
55
- metadata.add("authorization", `Bearer ${this.token}`);
76
+ const activeToken = this.lastResolvedToken || (typeof this.token === "string" ? this.token : void 0);
77
+ if (activeToken) {
78
+ metadata.add("authorization", `Bearer ${activeToken}`);
56
79
  }
57
80
  return this.client.ExecuteLogic(request, metadata);
58
81
  }
@@ -108,6 +131,7 @@ var LiopClient = class {
108
131
  serverInfo;
109
132
  verifier = new LiopVerifier();
110
133
  oauthToken;
134
+ tokenManager;
111
135
  /** Protocol negotiation era */
112
136
  era = "modern";
113
137
  /** Negotiated protocol version */
@@ -115,40 +139,6 @@ var LiopClient = class {
115
139
  constructor(tls) {
116
140
  this.tlsOptions = tls;
117
141
  }
118
- /**
119
- * Requests an M2M access token from the Nexus Authorization Server using Client Credentials.
120
- */
121
- async acquireM2MToken(authOpts) {
122
- const baseUrl = authOpts.nexusUrl.endsWith("/oidc") ? authOpts.nexusUrl : `${authOpts.nexusUrl}/oidc`;
123
- const tokenUrl = `${baseUrl}/token`;
124
- log.info(`[LiopClient] Requesting M2M Token from Nexus AS: ${tokenUrl}`);
125
- const params = new URLSearchParams({
126
- grant_type: "client_credentials",
127
- scope: authOpts.scope || "liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query",
128
- resource: authOpts.audience,
129
- client_id: authOpts.clientId,
130
- client_secret: authOpts.clientSecret
131
- });
132
- const response = await fetch(tokenUrl, {
133
- method: "POST",
134
- headers: {
135
- "Content-Type": "application/x-www-form-urlencoded"
136
- },
137
- body: params.toString()
138
- });
139
- if (!response.ok) {
140
- const text = await response.text();
141
- throw new Error(
142
- `OAuth token request failed with status ${response.status}: ${text}`
143
- );
144
- }
145
- const data = await response.json();
146
- if (!data.access_token) {
147
- throw new Error("OAuth token response did not contain an access_token.");
148
- }
149
- log.info("[LiopClient] M2M Token acquired successfully.");
150
- return data.access_token;
151
- }
152
142
  /**
153
143
  * Discovers and connects to the target server or mesh capability.
154
144
  * If address is omitted, it sets up the MeshNode to act purely dynamically.
@@ -161,14 +151,20 @@ var LiopClient = class {
161
151
  const scope = options?.auth?.scope || process.env.LIOP_OAUTH_SCOPE || "liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query";
162
152
  this.oauthToken = options?.auth?.token || process.env.LIOP_OAUTH_TOKEN || process.env.LIOP_TOKEN;
163
153
  if (clientId && clientSecret) {
154
+ const baseUrl = (nexusUrl).endsWith("/oidc") ? nexusUrl : `${nexusUrl}/oidc`;
155
+ const tokenEndpoint = `${baseUrl}/token`;
156
+ this.tokenManager = new TokenManager({
157
+ tokenEndpoint,
158
+ clientId,
159
+ clientSecret,
160
+ audience,
161
+ scopes: scope
162
+ });
164
163
  try {
165
- this.oauthToken = await this.acquireM2MToken({
166
- clientId,
167
- clientSecret,
168
- nexusUrl,
169
- audience,
170
- scope
171
- });
164
+ this.oauthToken = await this.tokenManager.getToken();
165
+ log.info(
166
+ "[LiopClient] Dynamic TokenManager configured and initial token acquired."
167
+ );
172
168
  } catch (err) {
173
169
  log.error(
174
170
  `[LiopClient] Failed to acquire OAuth M2M Token: ${err instanceof Error ? err.message : String(err)}`
@@ -181,9 +177,15 @@ var LiopClient = class {
181
177
  `[LiopClient] Mesh Node synchronized. PeerID: ${this.meshNode.getPeerId()}`
182
178
  );
183
179
  if (address) {
180
+ const tokenResolver = async () => {
181
+ if (this.tokenManager) {
182
+ return await this.tokenManager.getToken();
183
+ }
184
+ return this.oauthToken;
185
+ };
184
186
  this.rpcClients.set(
185
187
  "static",
186
- new LiopRpcClient(address, this.tlsOptions, this.oauthToken)
188
+ new LiopRpcClient(address, this.tlsOptions, tokenResolver)
187
189
  );
188
190
  this.serverInfo = { name: `LiopServer (${address})`, version: "1.0.0" };
189
191
  log.info(`[LiopClient] Static gRPC configured for: ${address}`);
@@ -313,6 +315,7 @@ var LiopClient = class {
313
315
  if (!this.meshNode) {
314
316
  throw new Error("Client must be connected before discovering tools.");
315
317
  }
318
+ const discoveryStartTime = Date.now();
316
319
  log.info(
317
320
  `[LiopClient] Discovery started (forceRefresh: ${forceRefresh})...`
318
321
  );
@@ -349,6 +352,19 @@ var LiopClient = class {
349
352
  log.info(
350
353
  `[LiopClient] Discovery finished. Found ${tools.length} unique tools.`
351
354
  );
355
+ try {
356
+ const telemetry = TokenTelemetryEngine.getInstance();
357
+ const toolsPayload = JSON.stringify(tools);
358
+ const toolsResponsePayload = JSON.stringify({ tools });
359
+ telemetry.record({
360
+ type: "tools_list",
361
+ method: "discoverTools",
362
+ estimatedInputTokens: telemetry.countTokens(toolsPayload),
363
+ estimatedOutputTokens: telemetry.countTokens(toolsResponsePayload),
364
+ durationMs: Date.now() - discoveryStartTime
365
+ });
366
+ } catch {
367
+ }
352
368
  return tools;
353
369
  }
354
370
  /**
@@ -358,6 +374,7 @@ var LiopClient = class {
358
374
  if (!this.meshNode) {
359
375
  throw new Error("Client must be connected before calling tools.");
360
376
  }
377
+ const callStartTime = Date.now();
361
378
  const toolName = request.name;
362
379
  log.info(`[LiopClient] Resolving Tool: ${toolName}`);
363
380
  let rpcClient = this.rpcClients.get("static");
@@ -405,13 +422,52 @@ var LiopClient = class {
405
422
  const agentDid = this.meshNode ? `did:liop:${this.meshNode.getPeerId()}` : "did:liop:ephemeral";
406
423
  const intentPayload = Buffer.from(`${toolName}:${Date.now()}`);
407
424
  const proofOfIntent = this.meshNode ? await this.meshNode.sign(intentPayload) : intentPayload;
408
- const intentResponse = await rpcClient.negotiateIntent({
409
- agent_did: agentDid,
410
- capability_hash: toolName,
411
- proof_of_intent: proofOfIntent
412
- });
425
+ let intentResponse;
426
+ try {
427
+ intentResponse = await rpcClient.negotiateIntent({
428
+ agent_did: agentDid,
429
+ capability_hash: toolName,
430
+ proof_of_intent: proofOfIntent
431
+ });
432
+ } catch (err) {
433
+ const errMsg = err instanceof Error ? err.message : String(err);
434
+ if (this.tokenManager && (errMsg.includes("UNAUTHENTICATED") || errMsg.includes("Invalid JWT") || errMsg.includes("timestamp check failed") || errMsg.includes("expired"))) {
435
+ log.warn(
436
+ `[LiopClient] Token expired/unauthenticated for ${toolName}. Preemptively refreshing OAuth token and retrying negotiateIntent...`
437
+ );
438
+ this.tokenManager.invalidate();
439
+ const freshToken = await this.tokenManager.getToken();
440
+ this.oauthToken = freshToken;
441
+ rpcClient.setToken(freshToken);
442
+ intentResponse = await rpcClient.negotiateIntent({
443
+ agent_did: agentDid,
444
+ capability_hash: toolName,
445
+ proof_of_intent: proofOfIntent
446
+ });
447
+ } else {
448
+ throw err;
449
+ }
450
+ }
413
451
  if (!intentResponse.accepted) {
414
- throw new Error(`Intent denied by host: ${intentResponse.error_message}`);
452
+ if (this.tokenManager && (intentResponse.error_message?.includes("token") || intentResponse.error_message?.includes("UNAUTHENTICATED") || intentResponse.error_message?.includes("expired") || intentResponse.error_message?.includes("timestamp check failed"))) {
453
+ log.warn(
454
+ `[LiopClient] Intent rejected with auth error: "${intentResponse.error_message}". Refreshing token and retrying...`
455
+ );
456
+ this.tokenManager.invalidate();
457
+ const freshToken = await this.tokenManager.getToken();
458
+ this.oauthToken = freshToken;
459
+ rpcClient.setToken(freshToken);
460
+ intentResponse = await rpcClient.negotiateIntent({
461
+ agent_did: agentDid,
462
+ capability_hash: toolName,
463
+ proof_of_intent: proofOfIntent
464
+ });
465
+ }
466
+ if (!intentResponse.accepted) {
467
+ throw new Error(
468
+ `Intent denied by host: ${intentResponse.error_message}`
469
+ );
470
+ }
415
471
  }
416
472
  const publicKey = intentResponse.kyber_public_key || intentResponse.kyberPublicKey;
417
473
  const sessionToken = intentResponse.session_token || intentResponse.sessionToken;
@@ -420,6 +476,13 @@ var LiopClient = class {
420
476
  "[LiopClient] Critical Error: Kyber Public Key not found in IntentResponse.",
421
477
  intentResponse
422
478
  );
479
+ try {
480
+ pqcHandshakesTotal.inc({
481
+ algorithm: "ml-kem-768",
482
+ status: "failure"
483
+ });
484
+ } catch {
485
+ }
423
486
  throw new Error(
424
487
  "Handshake failed: Remote host did not provide a valid Kyber Public Key."
425
488
  );
@@ -427,7 +490,29 @@ var LiopClient = class {
427
490
  log.info(
428
491
  `[LiopClient] Encapsulating Post-Quantum Shared Secret for ${request.name}...`
429
492
  );
430
- const { ciphertext: kyberCiphertext, sharedSecret } = await Kyber768Wrapper.encapsulateAsymmetric(publicKey);
493
+ const pqcStart = performance.now();
494
+ let kyberCiphertext;
495
+ let sharedSecret;
496
+ try {
497
+ const res = await Kyber768Wrapper.encapsulateAsymmetric(publicKey);
498
+ kyberCiphertext = res.ciphertext;
499
+ sharedSecret = res.sharedSecret;
500
+ const pqcDuration = performance.now() - pqcStart;
501
+ pqcHandshakeDurationMs.observe({ tool: request.name }, pqcDuration);
502
+ pqcHandshakesTotal.inc({
503
+ algorithm: "ml-kem-768",
504
+ status: "success"
505
+ });
506
+ } catch (encapError) {
507
+ try {
508
+ pqcHandshakesTotal.inc({
509
+ algorithm: "ml-kem-768",
510
+ status: "failure"
511
+ });
512
+ } catch {
513
+ }
514
+ throw encapError;
515
+ }
431
516
  log.info(`[LiopClient] Sealing WASM Payload and Inputs...`);
432
517
  const _safePayload = _wasmPayload || Buffer.from("");
433
518
  const { ciphertext: encryptedWasm, nonce: aesNonce } = AesGcmWrapper.encryptPayload(_safePayload, sharedSecret);
@@ -475,7 +560,20 @@ var LiopClient = class {
475
560
  Buffer.from(sharedSecret),
476
561
  response.semantic_evidence
477
562
  );
563
+ try {
564
+ zkVerificationsTotal.inc({
565
+ status: isValid ? "valid" : "invalid"
566
+ });
567
+ } catch {
568
+ }
478
569
  if (!isValid) {
570
+ try {
571
+ toolCallErrorsTotal.inc({
572
+ capability: toolName,
573
+ error_type: "zk_verification_failed"
574
+ });
575
+ } catch {
576
+ }
479
577
  reject(
480
578
  new Error(
481
579
  "PROTOCOL INTEGRITY VIOLATION: ZK-Receipt verification failed."
@@ -483,8 +581,34 @@ var LiopClient = class {
483
581
  );
484
582
  return;
485
583
  }
584
+ } else {
585
+ try {
586
+ toolCallErrorsTotal.inc({
587
+ capability: toolName,
588
+ error_type: "remote_execution_error"
589
+ });
590
+ } catch {
591
+ }
486
592
  }
487
593
  resultFulfilled = true;
594
+ try {
595
+ const telemetry = TokenTelemetryEngine.getInstance();
596
+ const inputPayload = JSON.stringify(request.arguments ?? {});
597
+ telemetry.record({
598
+ type: "tool_call",
599
+ method: "callTool",
600
+ toolName,
601
+ peerId: targetClientKey !== toolName ? targetClientKey : void 0,
602
+ estimatedInputTokens: telemetry.countTokens(inputPayload),
603
+ estimatedOutputTokens: telemetry.countTokens(
604
+ response.semantic_evidence
605
+ ),
606
+ durationMs: Date.now() - callStartTime
607
+ });
608
+ const egressBytes = Buffer.byteLength(response.semantic_evidence || "") + (response.cryptographic_proof ? response.cryptographic_proof.length : 0) + (response.zk_receipt ? response.zk_receipt.length : 0);
609
+ wireEgressBytesTotal.inc({ capability: toolName }, egressBytes);
610
+ } catch {
611
+ }
488
612
  resolve({
489
613
  content: [
490
614
  {
@@ -495,12 +619,26 @@ var LiopClient = class {
495
619
  isError: response.is_error
496
620
  });
497
621
  } catch (err) {
622
+ try {
623
+ toolCallErrorsTotal.inc({
624
+ capability: toolName,
625
+ error_type: "verification_exception"
626
+ });
627
+ } catch {
628
+ }
498
629
  reject(err);
499
630
  }
500
631
  });
501
632
  stream.on("error", (err) => {
502
633
  this.rpcClients.delete(targetClientKey);
503
634
  this.rpcClients.delete(toolName);
635
+ try {
636
+ toolCallErrorsTotal.inc({
637
+ capability: toolName,
638
+ error_type: "stream_error"
639
+ });
640
+ } catch {
641
+ }
504
642
  if (resultFulfilled) return;
505
643
  log.error("[LiopClient] Stream Error:", err);
506
644
  reject(err);
@@ -515,7 +653,6 @@ var LiopClient = class {
515
653
  getOrCreateRpcClient(peerId, address) {
516
654
  let client = this.rpcClients.get(peerId);
517
655
  if (!client) {
518
- let nodeToken = this.oauthToken;
519
656
  let manifest = this.manifests.get(peerId);
520
657
  let realPeerId = peerId;
521
658
  if (!manifest) {
@@ -560,9 +697,15 @@ var LiopClient = class {
560
697
  log.info(
561
698
  `[LiopClient] Resolved node-specific token for peer ${realPeerId.slice(-8)} (${providerName || "unknown"})`
562
699
  );
563
- nodeToken = envToken;
564
700
  }
565
- client = new LiopRpcClient(address, this.tlsOptions, nodeToken);
701
+ const tokenResolver = async () => {
702
+ if (envToken) return envToken;
703
+ if (this.tokenManager) {
704
+ return await this.tokenManager.getToken();
705
+ }
706
+ return this.oauthToken;
707
+ };
708
+ client = new LiopRpcClient(address, this.tlsOptions, tokenResolver);
566
709
  this.rpcClients.set(peerId, client);
567
710
  }
568
711
  return client;
@@ -575,6 +718,7 @@ var LiopClient = class {
575
718
  if (!this.meshNode) {
576
719
  throw new Error("Client must be connected before reading resources.");
577
720
  }
721
+ const readStartTime = Date.now();
578
722
  log.info(`[LiopClient] Querying Mesh for Resource: ${uri}...`);
579
723
  const providers = await this.meshNode.findProviders(uri);
580
724
  if (providers.length === 0) {
@@ -588,7 +732,7 @@ var LiopClient = class {
588
732
  if (!resourceDef) {
589
733
  throw new Error(`Resource ${uri} not listed in remote manifest.`);
590
734
  }
591
- return {
735
+ const result = {
592
736
  contents: [
593
737
  {
594
738
  uri,
@@ -597,6 +741,21 @@ var LiopClient = class {
597
741
  }
598
742
  ]
599
743
  };
744
+ try {
745
+ const telemetry = TokenTelemetryEngine.getInstance();
746
+ const outputPayload = JSON.stringify(result);
747
+ telemetry.record({
748
+ type: "resource_read",
749
+ method: "readResource",
750
+ toolName: uri,
751
+ peerId: providers[0],
752
+ estimatedInputTokens: telemetry.countTokens(uri),
753
+ estimatedOutputTokens: telemetry.countTokens(outputPayload),
754
+ durationMs: Date.now() - readStartTime
755
+ });
756
+ } catch {
757
+ }
758
+ return result;
600
759
  }
601
760
  getServerInfo() {
602
761
  return this.serverInfo;
@@ -611,6 +770,6 @@ var LiopClient = class {
611
770
  }
612
771
  };
613
772
 
614
- export { LiopClient, LiopRpcClient };
615
- //# sourceMappingURL=chunk-CRZBVFDV.js.map
616
- //# sourceMappingURL=chunk-CRZBVFDV.js.map
773
+ export { AesGcmWrapper, LiopClient, LiopRpcClient };
774
+ //# sourceMappingURL=chunk-T7R5HUFD.js.map
775
+ //# sourceMappingURL=chunk-T7R5HUFD.js.map