@nekzus/liop 2.0.0-alpha.27 → 2.0.0-alpha.29
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 +36 -9
- package/dist/bin/agent.js +1 -1
- package/dist/bin/agent.js.map +1 -1
- package/dist/bridge.d.ts +4 -2
- package/dist/bridge.js +1 -1
- package/dist/{chunk-7I6YJS3C.js → chunk-DQ6UW6L7.js} +2 -2
- package/dist/chunk-DQ6UW6L7.js.map +1 -0
- package/dist/chunk-L5A64CNT.js +54 -0
- package/dist/chunk-L5A64CNT.js.map +1 -0
- package/dist/chunk-N6FGTZ6A.js +3 -0
- package/dist/chunk-N6FGTZ6A.js.map +1 -0
- package/dist/chunk-RYYRR4N5.js +31 -0
- package/dist/chunk-RYYRR4N5.js.map +1 -0
- package/dist/chunk-SB5XJXKV.js +2 -0
- package/dist/chunk-SB5XJXKV.js.map +1 -0
- package/dist/{chunk-TNMS53OP.js → chunk-TYVG6TXQ.js} +2 -2
- package/dist/{chunk-TNMS53OP.js.map → chunk-TYVG6TXQ.js.map} +1 -1
- package/dist/chunk-VGXNGTIC.js +33 -0
- package/dist/chunk-VGXNGTIC.js.map +1 -0
- package/dist/chunk-W2QGWRTT.js +3 -0
- package/dist/chunk-W2QGWRTT.js.map +1 -0
- package/dist/chunk-YZVCAJJO.js +13 -0
- package/dist/chunk-YZVCAJJO.js.map +1 -0
- package/dist/client.d.ts +3 -2
- package/dist/client.js +1 -1
- package/dist/gateway.d.ts +14 -3
- package/dist/gateway.js +1 -1
- package/dist/{index-BihN3W-K.d.ts → index-B_Vbrb_I.d.ts} +14 -1
- package/dist/index-CL8m1L1d.d.ts +500 -0
- package/dist/index.d.ts +124 -6
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mesh.d.ts +3 -0
- package/dist/mesh.js +1 -1
- package/dist/server.d.ts +5 -377
- package/dist/server.js +1 -1
- package/dist/types-DzEXgi4s.d.ts +228 -0
- package/dist/types.d.ts +3 -148
- package/dist/types.js +1 -1
- package/dist/workers/logic-execution.js +1 -1
- package/dist/workers/logic-execution.js.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-7I6YJS3C.js.map +0 -1
- package/dist/chunk-AKTU6ZMX.js +0 -2
- package/dist/chunk-AKTU6ZMX.js.map +0 -1
- package/dist/chunk-BDQZURCS.js +0 -54
- package/dist/chunk-BDQZURCS.js.map +0 -1
- package/dist/chunk-GFRRQ2EB.js +0 -33
- package/dist/chunk-GFRRQ2EB.js.map +0 -1
- package/dist/chunk-GYK2HORK.js +0 -3
- package/dist/chunk-GYK2HORK.js.map +0 -1
- package/dist/chunk-RNS4FR5L.js +0 -31
- package/dist/chunk-RNS4FR5L.js.map +0 -1
- package/dist/chunk-YTIMVS2I.js +0 -13
- package/dist/chunk-YTIMVS2I.js.map +0 -1
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {a as a$1}from'./chunk-SW53FNSN.js';import {a as a$4}from'./chunk-DBXGYHKY.js';import {c,a}from'./chunk-V5MKJT6S.js';import {a as a$3}from'./chunk-DQ6UW6L7.js';import {a as a$2}from'./chunk-S6RJHZV2.js';import*as L from'@grpc/grpc-js';import {createDecipheriv,randomBytes,createCipheriv}from'crypto';var v=class{client;token;constructor(e,o,t){let i=c(o);this.client=new a.LogicMesh(e,i),this.token=t;}async negotiateIntent(e){return new Promise((o,t)=>{let i=new L.Metadata;this.token&&i.add("authorization",`Bearer ${this.token}`),this.client.NegotiateIntent(e,i,(n,s)=>{n?t(n):o(s);});})}executeLogic(e){let o=new L.Metadata;return this.token&&o.add("authorization",`Bearer ${this.token}`),this.client.ExecuteLogic(e,o)}close(){this.client.close();}};var M={encryptPayload(u,e){if(e.length!==32)throw new Error("Symmetric Key must be exactly 32 bytes (256 bits).");let o=randomBytes(12),t=createCipheriv("aes-256-gcm",e,o),i=Buffer.concat([t.update(u),t.final()]),n=t.getAuthTag();return {ciphertext:Buffer.concat([i,n]),nonce:o}},decryptPayload(u,e,o){if(u.length<16)throw new Error("Invalid GCM Ciphertext; missing authentication tag length");let t=u.subarray(0,-16),i=u.subarray(-16),n=createDecipheriv("aes-256-gcm",o,e);return n.setAuthTag(i),Buffer.concat([n.update(t),n.final()])}};var x=class{meshNode=null;rpcClients=new Map;manifests=new Map;tlsOptions;serverInfo;verifier=new a$1;oauthToken;constructor(e){this.tlsOptions=e;}async acquireM2MToken(e){let t=`${e.nexusUrl.endsWith("/oidc")?e.nexusUrl:`${e.nexusUrl}/oidc`}/token`;a$2.info(`[LiopClient] Requesting M2M Token from Nexus AS: ${t}`);let i=new URLSearchParams({grant_type:"client_credentials",scope:e.scope||"liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query",resource:e.audience,client_id:e.clientId,client_secret:e.clientSecret}),n=await fetch(t,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:i.toString()});if(!n.ok){let c=await n.text();throw new Error(`OAuth token request failed with status ${n.status}: ${c}`)}let s=await n.json();if(!s.access_token)throw new Error("OAuth token response did not contain an access_token.");return a$2.info("[LiopClient] M2M Token acquired successfully."),s.access_token}async connect(e,o){let t=o?.auth?.clientId||process.env.LIOP_OAUTH_CLIENT_ID||process.env.LIOP_CLIENT_ID,i=o?.auth?.clientSecret||process.env.LIOP_OAUTH_CLIENT_SECRET||process.env.LIOP_CLIENT_SECRET,n=o?.auth?.nexusUrl||process.env.LIOP_NEXUS_URL||"http://localhost:3000",s=o?.auth?.audience||process.env.LIOP_OAUTH_AUDIENCE||"urn:liop:mesh:api",c=o?.auth?.scope||process.env.LIOP_OAUTH_SCOPE||"liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query";if(this.oauthToken=o?.auth?.token||process.env.LIOP_OAUTH_TOKEN||process.env.LIOP_TOKEN,t&&i)try{this.oauthToken=await this.acquireM2MToken({clientId:t,clientSecret:i,nexusUrl:n,audience:s,scope:c});}catch(a){a$2.error(`[LiopClient] Failed to acquire OAuth M2M Token: ${a instanceof Error?a.message:String(a)}`);}this.meshNode=new a$3(o?.meshConfig),await this.meshNode.start(),a$2.info(`[LiopClient] Mesh Node synchronized. PeerID: ${this.meshNode.getPeerId()}`),e?(this.rpcClients.set("static",new v(e,this.tlsOptions,this.oauthToken)),this.serverInfo={name:`LiopServer (${e})`,version:"1.0.0"},a$2.info(`[LiopClient] Static gRPC configured for: ${e}`)):this.serverInfo={name:"LiopServer (Mesh Alpha)",version:"1.0.0"};}async resolveCapability(e){if(!this.meshNode)throw new Error("Client must be connected to Mesh to resolve capabilities.");a$2.info(`[LiopClient] Querying Mesh DHT for Provider: ${e}...`);let o=await this.meshNode.findProviders(e);if(o.length===0)throw new Error(`Kademlia DHT found zero providers for capability: ${e}`);let t=o[0];a$2.info(`[LiopClient] Identified Alpha Provider PeerID: ${t}`);let i=50051,n=await this.meshNode.queryManifest(t);n&&(i=n.grpcPort,a$2.info(`[LiopClient] Manifest resolved: gRPC port ${i}`));let s=await this.meshNode.resolvePeer(t);for(let c of s){let a=c.split("/");if(a[1]==="ip4"){let p=`${a[2]}:${i}`;return a$2.info(`[LiopClient] Translated Multiaddr to gRPC Target: ${p}`),p}}return `127.0.0.1:${i}`}async discoverTools(){if(!this.meshNode)throw new Error("Client must be connected before discovering tools.");a$2.info("[LiopClient] Discovery started...");let e=await this.meshNode.discoverManifestProviders(),o=[],t=new Set;for(let i of e)try{a$2.info(`[LiopClient] Querying manifest from: ${i}`);let n=await this.meshNode.queryManifest(i);if(n){this.manifests.set(i,n);for(let s of n.tools)t.has(s.name)||(o.push({name:s.name,description:s.description}),t.add(s.name));}}catch(n){a$2.info(`[LiopClient] Error querying manifest from ${i}:`,n instanceof Error?n.message:String(n));}return a$2.info(`[LiopClient] Discovery finished. Found ${o.length} unique tools.`),o}async callTool(e,o){if(!this.meshNode)throw new Error("Client must be connected before calling tools.");let t=e.name;a$2.info(`[LiopClient] Resolving Tool: ${t}`);let i=this.rpcClients.get("static");if(i)a$2.info(`[LiopClient] Using existing static gRPC connection for ${t}.`);else {let y=await this.resolveCapability(t);i=this.getOrCreateRpcClient(t,y);}a$2.info(`[LiopClient] Negotiating intent for ${t}...`);let n=this.meshNode?`did:liop:${this.meshNode.getPeerId()}`:"did:liop:ephemeral",s=Buffer.from(`${t}:${Date.now()}`),c=this.meshNode?await this.meshNode.sign(s):s,a=await i.negotiateIntent({agent_did:n,capability_hash:t,proof_of_intent:c});if(!a.accepted)throw new Error(`Intent denied by host: ${a.error_message}`);let p=a.kyber_public_key||a.kyberPublicKey,f=a.session_token||a.sessionToken;if(!p)throw a$2.info("[LiopClient] Critical Error: Kyber Public Key not found in IntentResponse.",a),new Error("Handshake failed: Remote host did not provide a valid Kyber Public Key.");a$2.info(`[LiopClient] Encapsulating Post-Quantum Shared Secret for ${e.name}...`);let{ciphertext:C,sharedSecret:g}=await a$4.encapsulateAsymmetric(p);a$2.info("[LiopClient] Sealing WASM Payload and Inputs...");let T=o||Buffer.from(""),{ciphertext:A,nonce:S}=M.encryptPayload(T,g),_={},I=await import('crypto');for(let[y,h]of Object.entries(e.arguments||{})){let m=I.randomBytes(12),d=I.createCipheriv("aes-256-gcm",g,m),w=Buffer.concat([d.update(JSON.stringify(h)),d.final()]),l=d.getAuthTag();_[y]=Buffer.concat([m,w,l]);}let U={session_token:f,wasm_binary:A,inputs:_,pqc_ciphertext:C,aes_nonce:S};return new Promise((y,h)=>{let m=i.executeLogic(U);if(!m){h(new Error("RPC Client unavailable or failed to create stream."));return}let d=false,w=false;m.on("data",async l=>{if(!d){w=true,a$2.info("[LiopClient] Logic Executed. Verification in progress...");try{if(!l.is_error&&!await this.verifier.verifyZkReceipt(T,Buffer.from(l.cryptographic_proof).toString("hex"),Buffer.from(l.zk_receipt),Buffer.from(g))){h(new Error("PROTOCOL INTEGRITY VIOLATION: ZK-Receipt verification failed."));return}d=!0,y({content:[{type:"text",text:l.semantic_evidence}],isError:l.is_error});}catch(P){h(P);}}}),m.on("error",l=>{d||(a$2.error("[LiopClient] Stream Error:",l),h(l));}),m.on("end",()=>{!w&&!d&&h(new Error("Logic-on-Origin stream closed without results."));});})}getOrCreateRpcClient(e,o){let t=this.rpcClients.get(e);if(!t){let i=this.oauthToken,n=this.manifests.get(e),s=e;if(!n){for(let[f,C]of this.manifests.entries())if(C.tools.some(g=>g.name===e)){n=C,s=f;break}}let c=n?.serverInfo?.name?.toLowerCase()||"",a,p=n?.tokenSlug;if(p&&(a=process.env[`LIOP_TOKEN_${p}`]||process.env[`LIOP_OAUTH_TOKEN_${p}`]),!a&&s){let f=s.slice(-8).toUpperCase();a=process.env[`LIOP_TOKEN_${f}`]||process.env[`LIOP_OAUTH_TOKEN_${f}`];}if(!a&&c){let f=c.toUpperCase().replace(/[^A-Z0-9_]/g,"_");a=process.env[`LIOP_TOKEN_${f}`]||process.env[`LIOP_OAUTH_TOKEN_${f}`];}a&&(a$2.info(`[LiopClient] Resolved node-specific token for peer ${s.slice(-8)} (${c||"unknown"})`),i=a),t=new v(o,this.tlsOptions,i),this.rpcClients.set(e,t);}return t}async readResource(e){if(!this.meshNode)throw new Error("Client must be connected before reading resources.");a$2.info(`[LiopClient] Querying Mesh for Resource: ${e}...`);let o=await this.meshNode.findProviders(e);if(o.length===0)throw new Error(`No mesh providers found for resource: ${e}`);let t=await this.meshNode.queryManifest(o[0]);if(!t)throw new Error("Target peer did not return a valid LIOP Manifest.");let i=t.resources?.find(n=>n.uri===e);if(!i)throw new Error(`Resource ${e} not listed in remote manifest.`);return {contents:[{uri:e,mimeType:i.mimeType||"application/json",text:JSON.stringify(i,null,2)}]}}getServerInfo(){return this.serverInfo}async close(){this.meshNode&&await this.meshNode.stop();}};
|
|
2
|
+
export{v as a,x as b};//# sourceMappingURL=chunk-N6FGTZ6A.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-N6FGTZ6A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rpc/client.ts","../src/rpc/crypto/aes.ts","../src/client/index.ts"],"names":["LiopRpcClient","address","tls","token","credentials","createChannelCredentials","liopV1","request","resolve","reject","metadata","error","response","AesGcmWrapper","payload","sharedSecret","nonce","randomBytes","cipher","createCipheriv","encrypted","authTag","ciphertextBuffer","encryptedData","decipher","createDecipheriv","LiopClient","LiopVerifier","authOpts","tokenUrl","log","params","text","data","options","clientId","clientSecret","nexusUrl","audience","scope","err","MeshNode","toolName","providers","providerId","grpcPort","manifest","addrs","maddr","parts","grpcHost","providerIds","tools","seenNames","peerId","tool","_wasmPayload","rpcClient","dynamicAddress","agentDid","intentPayload","proofOfIntent","intentResponse","publicKey","sessionToken","kyberCiphertext","Kyber768Wrapper","_safePayload","encryptedWasm","aesNonce","encryptedInputs","crypto","key","value","inputNonce","logicRequest","stream","resultFulfilled","hasReceivedData","client","nodeToken","realPeerId","pId","m","t","providerName","envToken","slug","shortId","cleanName","uri","resourceDef","r"],"mappings":"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","file":"chunk-N6FGTZ6A.js","sourcesContent":["import * as grpc from \"@grpc/grpc-js\";\nimport { liopV1 } from \"./proto.js\";\nimport { createChannelCredentials, type LiopTlsOptions } from \"./tls.js\";\nimport type {\n\tIntentRequest,\n\tIntentResponse,\n\tLogicRequest,\n\tLogicResponse,\n} from \"./types.js\";\n\n/**\n * LIOP gRPC Client Implementation\n * Provides a high-level interface for secure intent negotiation and logic execution.\n */\nexport class LiopRpcClient {\n\t// biome-ignore lint/suspicious/noExplicitAny: internal gRPC client type\n\tprivate client: any;\n\tprivate token?: string;\n\n\tconstructor(address: string, tls?: LiopTlsOptions, token?: string) {\n\t\tconst credentials = createChannelCredentials(tls);\n\t\tthis.client = new liopV1.LogicMesh(address, credentials);\n\t\tthis.token = token;\n\t}\n\n\t/**\n\t * Negotiates intent with the remote host.\n\t * Returns the ephemeral Kyber public key for payload encryption.\n\t */\n\tpublic async negotiateIntent(\n\t\trequest: IntentRequest,\n\t): Promise<IntentResponse> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst metadata = new grpc.Metadata();\n\t\t\tif (this.token) {\n\t\t\t\tmetadata.add(\"authorization\", `Bearer ${this.token}`);\n\t\t\t}\n\t\t\tthis.client.NegotiateIntent(\n\t\t\t\trequest,\n\t\t\t\tmetadata,\n\t\t\t\t(error: grpc.ServiceError | null, response: IntentResponse) => {\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresolve(response);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Pushes the encrypted Logic-on-Origin payload to the origin.\n\t * Returns a stream of semantic responses and ZK proofs.\n\t */\n\tpublic executeLogic(\n\t\trequest: LogicRequest,\n\t): grpc.ClientReadableStream<LogicResponse> {\n\t\tconst metadata = new grpc.Metadata();\n\t\tif (this.token) {\n\t\t\tmetadata.add(\"authorization\", `Bearer ${this.token}`);\n\t\t}\n\t\treturn this.client.ExecuteLogic(request, metadata);\n\t}\n\n\tpublic close(): void {\n\t\tthis.client.close();\n\t}\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\n\n/**\n * LIOP Symmetric Payload Encryption Wrapper\n * Uses AES-256-GCM to secure WASM Code transport over Zero-Trust networks.\n * Fully compatible with the `aes-gcm` Rust crate used by Wasmtime.\n */\nexport const AesGcmWrapper = {\n\t/**\n\t * Encrypts a raw WASM payload using the shared secret negotiated via Kyber768.\n\t *\n\t * @param payload Raw incoming WASM byte array or string.\n\t * @param sharedSecret A perfectly derived 32-byte (256-bit) shared secret array\n\t * @returns The encrypted buffer to push to the GRPc stream, along with the 12-byte initialization vector natively generated.\n\t */\n\tencryptPayload(\n\t\tpayload: Uint8Array | Buffer,\n\t\tsharedSecret: Uint8Array,\n\t): {\n\t\tciphertext: Buffer;\n\t\tnonce: Buffer;\n\t} {\n\t\tif (sharedSecret.length !== 32) {\n\t\t\tthrow new Error(\"Symmetric Key must be exactly 32 bytes (256 bits).\");\n\t\t}\n\n\t\t// LIOP standard demands 96-bit (12 byte) IVs/Nonces for AES-GCM\n\t\tconst nonce = randomBytes(12);\n\n\t\tconst cipher = createCipheriv(\"aes-256-gcm\", sharedSecret, nonce);\n\n\t\t// Encrypt the payload and seal the tag\n\t\tconst encrypted = Buffer.concat([cipher.update(payload), cipher.final()]);\n\t\tconst authTag = cipher.getAuthTag(); // 16 bytes for GCM integrity\n\n\t\t// In LIOP, the auth tag is strictly appended to the end of the ciphertext bytes\n\t\t// mirroring the default serialization logic within `aes_gcm::Aes256Gcm` in Rust\n\t\tconst finalCiphertext = Buffer.concat([encrypted, authTag]);\n\n\t\treturn {\n\t\t\tciphertext: finalCiphertext,\n\t\t\tnonce: nonce,\n\t\t};\n\t},\n\n\t/**\n\t * Decrypts a remote Zero-Knowledge receipt using AES-256-GCM.\n\t */\n\tdecryptPayload(\n\t\tciphertextBuffer: Buffer,\n\t\tnonce: Buffer,\n\t\tsharedSecret: Uint8Array,\n\t): Buffer {\n\t\tif (ciphertextBuffer.length < 16) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Invalid GCM Ciphertext; missing authentication tag length\",\n\t\t\t);\n\t\t}\n\n\t\t// The last 16 bytes represent the AuthTag appended by rust-aes-gcm\n\t\tconst encryptedData = ciphertextBuffer.subarray(0, -16);\n\t\tconst authTag = ciphertextBuffer.subarray(-16);\n\n\t\tconst decipher = createDecipheriv(\"aes-256-gcm\", sharedSecret, nonce);\n\t\tdecipher.setAuthTag(authTag);\n\n\t\treturn Buffer.concat([decipher.update(encryptedData), decipher.final()]);\n\t},\n};\n","import { LiopVerifier } from \"../crypto/verifier.js\";\nimport {\n\ttype LiopManifest,\n\tMeshNode,\n\ttype MeshNodeConfig,\n} from \"../mesh/node.js\";\nimport { LiopRpcClient } from \"../rpc/client.js\";\nimport { AesGcmWrapper } from \"../rpc/crypto/aes.js\";\nimport { Kyber768Wrapper } from \"../rpc/crypto/kyber.js\";\nimport type { LiopTlsOptions } from \"../rpc/tls.js\";\nimport type { LogicRequest, LogicResponse } from \"../rpc/types.js\";\nimport type { CallToolRequest, CallToolResult } from \"../types.js\";\nimport { log } from \"../utils/logger.js\";\n\n/**\n * LIOP Client\n * High-level orchestration for discovery and execution in the Logic-Injection-on-Origin mesh.\n */\nexport class LiopClient {\n\tprivate meshNode: MeshNode | null = null;\n\tprivate rpcClients: Map<string, LiopRpcClient> = new Map();\n\tprivate manifests: Map<string, LiopManifest> = new Map();\n\tprivate tlsOptions?: LiopTlsOptions;\n\tprivate serverInfo?: { name: string; version: string };\n\tpublic verifier: LiopVerifier = new LiopVerifier();\n\tprivate oauthToken?: string;\n\n\tconstructor(tls?: LiopTlsOptions) {\n\t\tthis.tlsOptions = tls;\n\t}\n\n\t/**\n\t * Requests an M2M access token from the Nexus Authorization Server using Client Credentials.\n\t */\n\tprivate async acquireM2MToken(authOpts: {\n\t\tclientId: string;\n\t\tclientSecret: string;\n\t\tnexusUrl: string;\n\t\taudience: string;\n\t\tscope?: string;\n\t}): Promise<string> {\n\t\tconst baseUrl = authOpts.nexusUrl.endsWith(\"/oidc\")\n\t\t\t? authOpts.nexusUrl\n\t\t\t: `${authOpts.nexusUrl}/oidc`;\n\t\tconst tokenUrl = `${baseUrl}/token`;\n\t\tlog.info(`[LiopClient] Requesting M2M Token from Nexus AS: ${tokenUrl}`);\n\n\t\tconst params = new URLSearchParams({\n\t\t\tgrant_type: \"client_credentials\",\n\t\t\tscope:\n\t\t\t\tauthOpts.scope ||\n\t\t\t\t\"liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query\",\n\t\t\tresource: authOpts.audience,\n\t\t\tclient_id: authOpts.clientId,\n\t\t\tclient_secret: authOpts.clientSecret,\n\t\t});\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t},\n\t\t\tbody: params.toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst text = await response.text();\n\t\t\tthrow new Error(\n\t\t\t\t`OAuth token request failed with status ${response.status}: ${text}`,\n\t\t\t);\n\t\t}\n\n\t\tconst data = (await response.json()) as {\n\t\t\taccess_token: string;\n\t\t\texpires_in?: number;\n\t\t};\n\t\tif (!data.access_token) {\n\t\t\tthrow new Error(\"OAuth token response did not contain an access_token.\");\n\t\t}\n\n\t\tlog.info(\"[LiopClient] M2M Token acquired successfully.\");\n\t\treturn data.access_token;\n\t}\n\n\t/**\n\t * Discovers and connects to the target server or mesh capability.\n\t * If address is omitted, it sets up the MeshNode to act purely dynamically.\n\t */\n\tpublic async connect(\n\t\taddress?: string,\n\t\toptions?: {\n\t\t\tmeshConfig?: MeshNodeConfig;\n\t\t\tauth?: {\n\t\t\t\tclientId?: string;\n\t\t\t\tclientSecret?: string;\n\t\t\t\tnexusUrl?: string;\n\t\t\t\taudience?: string;\n\t\t\t\tscope?: string;\n\t\t\t\ttoken?: string;\n\t\t\t};\n\t\t},\n\t): Promise<void> {\n\t\t// Attempt to acquire OAuth M2M access token if credentials are provided\n\t\tconst clientId =\n\t\t\toptions?.auth?.clientId ||\n\t\t\tprocess.env.LIOP_OAUTH_CLIENT_ID ||\n\t\t\tprocess.env.LIOP_CLIENT_ID;\n\t\tconst clientSecret =\n\t\t\toptions?.auth?.clientSecret ||\n\t\t\tprocess.env.LIOP_OAUTH_CLIENT_SECRET ||\n\t\t\tprocess.env.LIOP_CLIENT_SECRET;\n\t\tconst nexusUrl =\n\t\t\toptions?.auth?.nexusUrl ||\n\t\t\tprocess.env.LIOP_NEXUS_URL ||\n\t\t\t\"http://localhost:3000\";\n\t\tconst audience =\n\t\t\toptions?.auth?.audience ||\n\t\t\tprocess.env.LIOP_OAUTH_AUDIENCE ||\n\t\t\t\"urn:liop:mesh:api\";\n\t\tconst scope =\n\t\t\toptions?.auth?.scope ||\n\t\t\tprocess.env.LIOP_OAUTH_SCOPE ||\n\t\t\t\"liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query\";\n\n\t\tthis.oauthToken =\n\t\t\toptions?.auth?.token ||\n\t\t\tprocess.env.LIOP_OAUTH_TOKEN ||\n\t\t\tprocess.env.LIOP_TOKEN;\n\n\t\tif (clientId && clientSecret) {\n\t\t\ttry {\n\t\t\t\tthis.oauthToken = await this.acquireM2MToken({\n\t\t\t\t\tclientId,\n\t\t\t\t\tclientSecret,\n\t\t\t\t\tnexusUrl,\n\t\t\t\t\taudience,\n\t\t\t\t\tscope,\n\t\t\t\t});\n\t\t\t} catch (err: unknown) {\n\t\t\t\tlog.error(\n\t\t\t\t\t`[LiopClient] Failed to acquire OAuth M2M Token: ${\n\t\t\t\t\t\terr instanceof Error ? err.message : String(err)\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t\t// In development or when using static local token, allow connection to proceed\n\t\t\t}\n\t\t}\n\n\t\tthis.meshNode = new MeshNode(options?.meshConfig);\n\t\tawait this.meshNode.start();\n\t\tlog.info(\n\t\t\t`[LiopClient] Mesh Node synchronized. PeerID: ${this.meshNode.getPeerId()}`,\n\t\t);\n\n\t\tif (address) {\n\t\t\tthis.rpcClients.set(\n\t\t\t\t\"static\",\n\t\t\t\tnew LiopRpcClient(address, this.tlsOptions, this.oauthToken),\n\t\t\t);\n\t\t\tthis.serverInfo = { name: `LiopServer (${address})`, version: \"1.0.0\" };\n\t\t\tlog.info(`[LiopClient] Static gRPC configured for: ${address}`);\n\t\t} else {\n\t\t\tthis.serverInfo = { name: \"LiopServer (Mesh Alpha)\", version: \"1.0.0\" };\n\t\t}\n\t}\n\n\t/**\n\t * Dynamically queries Kademlia DHT to find the optimal PeerID providing the Capability\n\t * and returns the physical gRPC target (host:port) resolved from the provider's manifest.\n\t */\n\tpublic async resolveCapability(toolName: string): Promise<string> {\n\t\tif (!this.meshNode)\n\t\t\tthrow new Error(\n\t\t\t\t\"Client must be connected to Mesh to resolve capabilities.\",\n\t\t\t);\n\n\t\tlog.info(`[LiopClient] Querying Mesh DHT for Provider: ${toolName}...`);\n\t\tconst providers = await this.meshNode.findProviders(toolName);\n\n\t\tif (providers.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Kademlia DHT found zero providers for capability: ${toolName}`,\n\t\t\t);\n\t\t}\n\n\t\tconst providerId = providers[0];\n\t\tlog.info(`[LiopClient] Identified Alpha Provider PeerID: ${providerId}`);\n\n\t\tlet grpcPort = 50051;\n\t\tconst manifest = await this.meshNode.queryManifest(providerId);\n\t\tif (manifest) {\n\t\t\tgrpcPort = manifest.grpcPort;\n\t\t\tlog.info(`[LiopClient] Manifest resolved: gRPC port ${grpcPort}`);\n\t\t}\n\n\t\tconst addrs = await this.meshNode.resolvePeer(providerId);\n\t\tfor (const maddr of addrs) {\n\t\t\tconst parts = maddr.split(\"/\");\n\t\t\tif (parts[1] === \"ip4\") {\n\t\t\t\tconst grpcHost = `${parts[2]}:${grpcPort}`;\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LiopClient] Translated Multiaddr to gRPC Target: ${grpcHost}`,\n\t\t\t\t);\n\t\t\t\treturn grpcHost;\n\t\t\t}\n\t\t}\n\n\t\treturn `127.0.0.1:${grpcPort}`;\n\t}\n\n\t/**\n\t * Discovers remote capabilities via the LIOP Manifest Protocol.\n\t */\n\tpublic async discoverTools(): Promise<\n\t\t{ name: string; description?: string }[]\n\t> {\n\t\tif (!this.meshNode) {\n\t\t\tthrow new Error(\"Client must be connected before discovering tools.\");\n\t\t}\n\n\t\tlog.info(`[LiopClient] Discovery started...`);\n\t\tconst providerIds = await this.meshNode.discoverManifestProviders();\n\t\tconst tools: { name: string; description?: string }[] = [];\n\t\tconst seenNames = new Set<string>();\n\n\t\tfor (const peerId of providerIds) {\n\t\t\ttry {\n\t\t\t\tlog.info(`[LiopClient] Querying manifest from: ${peerId}`);\n\t\t\t\tconst manifest = await this.meshNode.queryManifest(peerId);\n\t\t\t\tif (manifest) {\n\t\t\t\t\tthis.manifests.set(peerId, manifest);\n\t\t\t\t\tfor (const tool of manifest.tools) {\n\t\t\t\t\t\tif (!seenNames.has(tool.name)) {\n\t\t\t\t\t\t\ttools.push({ name: tool.name, description: tool.description });\n\t\t\t\t\t\t\tseenNames.add(tool.name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (err: unknown) {\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LiopClient] Error querying manifest from ${peerId}:`,\n\t\t\t\t\terr instanceof Error ? err.message : String(err),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tlog.info(\n\t\t\t`[LiopClient] Discovery finished. Found ${tools.length} unique tools.`,\n\t\t);\n\t\treturn tools;\n\t}\n\n\t/**\n\t * Invokes a tool.\n\t */\n\tpublic async callTool(\n\t\trequest: CallToolRequest,\n\t\t_wasmPayload?: Buffer,\n\t): Promise<CallToolResult> {\n\t\tif (!this.meshNode) {\n\t\t\tthrow new Error(\"Client must be connected before calling tools.\");\n\t\t}\n\n\t\tconst toolName = request.name;\n\t\tlog.info(`[LiopClient] Resolving Tool: ${toolName}`);\n\n\t\t// [ALPHA-FIX] Bypass DHT discovery if we are already statically connected to a provider (Enterprise/Test mode)\n\t\tlet rpcClient = this.rpcClients.get(\"static\");\n\n\t\tif (!rpcClient) {\n\t\t\tconst dynamicAddress = await this.resolveCapability(toolName);\n\t\t\trpcClient = this.getOrCreateRpcClient(toolName, dynamicAddress);\n\t\t} else {\n\t\t\tlog.info(\n\t\t\t\t`[LiopClient] Using existing static gRPC connection for ${toolName}.`,\n\t\t\t);\n\t\t}\n\n\t\tlog.info(`[LiopClient] Negotiating intent for ${toolName}...`);\n\t\tconst agentDid = this.meshNode\n\t\t\t? `did:liop:${this.meshNode.getPeerId()}`\n\t\t\t: \"did:liop:ephemeral\";\n\t\tconst intentPayload = Buffer.from(`${toolName}:${Date.now()}`);\n\t\tconst proofOfIntent = this.meshNode\n\t\t\t? await this.meshNode.sign(intentPayload)\n\t\t\t: intentPayload;\n\n\t\tconst intentResponse = (await rpcClient.negotiateIntent({\n\t\t\tagent_did: agentDid,\n\t\t\tcapability_hash: toolName,\n\t\t\tproof_of_intent: proofOfIntent,\n\t\t})) as unknown as {\n\t\t\taccepted: boolean;\n\t\t\terror_message: string;\n\t\t\tkyber_public_key: Uint8Array;\n\t\t\tkyberPublicKey: Uint8Array;\n\t\t\tsession_token: string;\n\t\t\tsessionToken: string;\n\t\t};\n\n\t\tif (!intentResponse.accepted) {\n\t\t\tthrow new Error(`Intent denied by host: ${intentResponse.error_message}`);\n\t\t}\n\n\t\t// LIOP Robust Field Extraction (Supports both snake_case and camelCase via gRPC-JS)\n\t\tconst publicKey =\n\t\t\tintentResponse.kyber_public_key || intentResponse.kyberPublicKey;\n\t\tconst sessionToken =\n\t\t\tintentResponse.session_token || intentResponse.sessionToken;\n\n\t\tif (!publicKey) {\n\t\t\tlog.info(\n\t\t\t\t\"[LiopClient] Critical Error: Kyber Public Key not found in IntentResponse.\",\n\t\t\t\tintentResponse,\n\t\t\t);\n\t\t\tthrow new Error(\n\t\t\t\t\"Handshake failed: Remote host did not provide a valid Kyber Public Key.\",\n\t\t\t);\n\t\t}\n\n\t\t// 2. Post-Quantum Encapsulation (ML-KEM-768)\n\t\tlog.info(\n\t\t\t`[LiopClient] Encapsulating Post-Quantum Shared Secret for ${request.name}...`,\n\t\t);\n\t\tconst { ciphertext: kyberCiphertext, sharedSecret } =\n\t\t\tawait Kyber768Wrapper.encapsulateAsymmetric(publicKey);\n\n\t\t// 3. Symmetric Sealing (AES-256-GCM)\n\t\tlog.info(`[LiopClient] Sealing WASM Payload and Inputs...`);\n\n\t\tconst _safePayload = _wasmPayload || Buffer.from(\"\");\n\n\t\t// Encrypt WASM binary\n\t\tconst { ciphertext: encryptedWasm, nonce: aesNonce } =\n\t\t\tAesGcmWrapper.encryptPayload(_safePayload, sharedSecret);\n\n\t\t// Encrypt inputs using a fresh random nonce per input to prevent AES-GCM nonce reuse\n\t\tconst encryptedInputs: Record<string, Uint8Array> = {};\n\t\tconst crypto = await import(\"node:crypto\");\n\t\tfor (const [key, value] of Object.entries(request.arguments || {})) {\n\t\t\tconst inputNonce = crypto.randomBytes(12);\n\t\t\tconst cipher = crypto.createCipheriv(\n\t\t\t\t\"aes-256-gcm\",\n\t\t\t\tsharedSecret,\n\t\t\t\tinputNonce,\n\t\t\t);\n\t\t\tconst encrypted = Buffer.concat([\n\t\t\t\tcipher.update(JSON.stringify(value)),\n\t\t\t\tcipher.final(),\n\t\t\t]);\n\t\t\tconst authTag = cipher.getAuthTag();\n\t\t\t// Prepend the 12-byte nonce to the ciphertext\n\t\t\tencryptedInputs[key] = Buffer.concat([inputNonce, encrypted, authTag]);\n\t\t}\n\n\t\t// 4. Assemble and Execute gRPC LogicRequest\n\t\tconst logicRequest: LogicRequest = {\n\t\t\tsession_token: sessionToken,\n\t\t\twasm_binary: encryptedWasm,\n\t\t\tinputs: encryptedInputs,\n\t\t\tpqc_ciphertext: kyberCiphertext,\n\t\t\taes_nonce: aesNonce,\n\t\t};\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst stream = rpcClient.executeLogic(logicRequest);\n\t\t\tif (!stream) {\n\t\t\t\treject(new Error(\"RPC Client unavailable or failed to create stream.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet resultFulfilled = false;\n\t\t\tlet hasReceivedData = false;\n\n\t\t\tstream.on(\"data\", async (response: LogicResponse) => {\n\t\t\t\tif (resultFulfilled) return;\n\t\t\t\thasReceivedData = true;\n\n\t\t\t\tlog.info(\"[LiopClient] Logic Executed. Verification in progress...\");\n\n\t\t\t\ttry {\n\t\t\t\t\t// Only verify ZK-Receipt if the remote execution succeeded.\n\t\t\t\t\t// If the remote execution failed due to a policy error (e.g. Egress Shield),\n\t\t\t\t\t// the ZK proof is empty and we should bypass validation to propagate the original error.\n\t\t\t\t\tif (!response.is_error) {\n\t\t\t\t\t\tconst isValid = await this.verifier.verifyZkReceipt(\n\t\t\t\t\t\t\t_safePayload,\n\t\t\t\t\t\t\tBuffer.from(response.cryptographic_proof).toString(\"hex\"),\n\t\t\t\t\t\t\tBuffer.from(response.zk_receipt),\n\t\t\t\t\t\t\tBuffer.from(sharedSecret),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t\"PROTOCOL INTEGRITY VIOLATION: ZK-Receipt verification failed.\",\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tresultFulfilled = true;\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: response.semantic_evidence,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tisError: response.is_error,\n\t\t\t\t\t});\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tstream.on(\"error\", (err) => {\n\t\t\t\tif (resultFulfilled) return;\n\t\t\t\tlog.error(\"[LiopClient] Stream Error:\", err);\n\t\t\t\treject(err);\n\t\t\t});\n\n\t\t\tstream.on(\"end\", () => {\n\t\t\t\t// We don't throw here if we already received a response block that is currently\n\t\t\t\t// undergoing ZK Verification in the Piscina worker pool.\n\t\t\t\tif (!hasReceivedData && !resultFulfilled) {\n\t\t\t\t\treject(new Error(\"Logic-on-Origin stream closed without results.\"));\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate getOrCreateRpcClient(peerId: string, address: string): LiopRpcClient {\n\t\tlet client = this.rpcClients.get(peerId);\n\t\tif (!client) {\n\t\t\tlet nodeToken = this.oauthToken;\n\n\t\t\tlet manifest = this.manifests.get(peerId);\n\t\t\tlet realPeerId = peerId;\n\n\t\t\t// If peerId is actually a toolName (which happens when called from callTool),\n\t\t\t// resolve the real PeerID and its manifest from the manifest cache.\n\t\t\tif (!manifest) {\n\t\t\t\tfor (const [pId, m] of this.manifests.entries()) {\n\t\t\t\t\tif (m.tools.some((t) => t.name === peerId)) {\n\t\t\t\t\t\tmanifest = m;\n\t\t\t\t\t\trealPeerId = pId;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst providerName = manifest?.serverInfo?.name?.toLowerCase() || \"\";\n\t\t\tlet envToken: string | undefined;\n\n\t\t\t// 0. Deterministic tokenSlug resolution (highest priority, zero heuristic)\n\t\t\tconst slug = manifest?.tokenSlug;\n\t\t\tif (slug) {\n\t\t\t\tenvToken =\n\t\t\t\t\tprocess.env[`LIOP_TOKEN_${slug}`] ||\n\t\t\t\t\tprocess.env[`LIOP_OAUTH_TOKEN_${slug}`];\n\t\t\t}\n\n\t\t\t// 1. PeerID-specific resolution: LIOP_TOKEN_<last 8 chars of PeerID in uppercase>\n\t\t\tif (!envToken && realPeerId) {\n\t\t\t\tconst shortId = realPeerId.slice(-8).toUpperCase();\n\t\t\t\tenvToken =\n\t\t\t\t\tprocess.env[`LIOP_TOKEN_${shortId}`] ||\n\t\t\t\t\tprocess.env[`LIOP_OAUTH_TOKEN_${shortId}`];\n\t\t\t}\n\n\t\t\t// 2. Provider-name resolution: LIOP_TOKEN_<CLEAN_PROVIDER_NAME_UPPERCASE>\n\t\t\tif (!envToken && providerName) {\n\t\t\t\tconst cleanName = providerName\n\t\t\t\t\t.toUpperCase()\n\t\t\t\t\t.replace(/[^A-Z0-9_]/g, \"_\");\n\t\t\t\tenvToken =\n\t\t\t\t\tprocess.env[`LIOP_TOKEN_${cleanName}`] ||\n\t\t\t\t\tprocess.env[`LIOP_OAUTH_TOKEN_${cleanName}`];\n\t\t\t}\n\n\t\t\tif (envToken) {\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LiopClient] Resolved node-specific token for peer ${realPeerId.slice(-8)} (${providerName || \"unknown\"})`,\n\t\t\t\t);\n\t\t\t\tnodeToken = envToken;\n\t\t\t}\n\n\t\t\tclient = new LiopRpcClient(address, this.tlsOptions, nodeToken);\n\t\t\tthis.rpcClients.set(peerId, client);\n\t\t}\n\t\treturn client;\n\t}\n\n\t/**\n\t * Reads a specific resource by URI.\n\t * In LIOP, resources can be static definitions or dynamic streams.\n\t */\n\tpublic async readResource(uri: string): Promise<{\n\t\tcontents: Array<{ uri: string; mimeType?: string; text: string }>;\n\t}> {\n\t\tif (!this.meshNode) {\n\t\t\tthrow new Error(\"Client must be connected before reading resources.\");\n\t\t}\n\t\tlog.info(`[LiopClient] Querying Mesh for Resource: ${uri}...`);\n\n\t\t// We search for the peer hosting the resource in the P2P Mesh\n\t\tconst providers = await this.meshNode.findProviders(uri);\n\t\tif (providers.length === 0) {\n\t\t\tthrow new Error(`No mesh providers found for resource: ${uri}`);\n\t\t}\n\n\t\t// Query the remote peer's manifest\n\t\tconst manifest = await this.meshNode.queryManifest(providers[0]);\n\t\tif (!manifest) {\n\t\t\tthrow new Error(\"Target peer did not return a valid LIOP Manifest.\");\n\t\t}\n\n\t\t// Locate the exact resource metadata\n\t\tconst resourceDef = manifest.resources?.find((r) => r.uri === uri);\n\t\tif (!resourceDef) {\n\t\t\tthrow new Error(`Resource ${uri} not listed in remote manifest.`);\n\t\t}\n\n\t\t// Return the declarative metadata (Logic-Injection is required for actual data extraction)\n\t\treturn {\n\t\t\tcontents: [\n\t\t\t\t{\n\t\t\t\t\turi,\n\t\t\t\t\tmimeType: resourceDef.mimeType || \"application/json\",\n\t\t\t\t\ttext: JSON.stringify(resourceDef, null, 2),\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\t}\n\n\tpublic getServerInfo(): { name: string; version: string } | undefined {\n\t\treturn this.serverInfo;\n\t}\n\n\t/**\n\t * Destroys the active Mesh Node resources.\n\t */\n\tpublic async close(): Promise<void> {\n\t\tif (this.meshNode) {\n\t\t\tawait this.meshNode.stop();\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import j from'crypto';import*as i from'fs/promises';import*as S from'os';import*as u from'path';import E from'vm';import {WASI}from'wasi';var l=class extends Error{constructor(r){super(`AST Sec-Policy Violation: ${r}`),this.name="GuardianError";}},w={analyze(c){let r=WebAssembly.Module.imports(c),o=0,d=new Set(["fd_write","fd_read","fd_close","fd_seek","environ_get","environ_sizes_get","args_get","args_sizes_get","clock_time_get","random_get","proc_exit","fd_prestat_get","fd_prestat_dir_name","fd_fdstat_get"]);for(let n of r){if(n.module==="wasi_snapshot_preview1"){if(!d.has(n.name))throw new l(`Banned WASI Import Detected: ${n.module}/${n.name}`)}else throw new l(`Banned Host Import Module Detected: ${n.module}`);if(o++,o>128)throw new l("Import limit exceeded. Possible resource exhaustion attack.")}}};var x=process.emit;process.emit=(c,r,...o)=>c==="warning"&&typeof r=="object"&&r.name==="ExperimentalWarning"&&String(r.message).includes("WASI")||String(r.message).includes("importing WASI")?false:x.call(process,c,r,...o);function R(){let r=process.platform==="win32"?["APPDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","PATH","PROCESSOR_ARCHITECTURE","SYSTEMDRIVE","SYSTEMROOT","TEMP","USERNAME","USERPROFILE","PROGRAMFILES"]:["HOME","LOGNAME","PATH","SHELL","TERM","USER"],o={NODE_ENV:"production",LIOP_NODE:"true"};for(let d of r){let n=process.env[d];n!==void 0&&!n.startsWith("()")&&(o[d]=n);}return o}var h=class{wasi;sandboxId;workingDir;config;stdoutHandle=null;stderrHandle=null;constructor(r={}){this.sandboxId=j.randomUUID(),this.workingDir=u.join(S.tmpdir(),"liop-mesh","sandboxes",this.sandboxId),this.config=r;}async init(){try{await i.mkdir(this.workingDir,{recursive:!0}),this.stdoutHandle=await i.open(u.join(this.workingDir,"stdout.log"),"w+"),this.stderrHandle=await i.open(u.join(this.workingDir,"stderr.log"),"w+"),this.wasi=new WASI({version:"preview1",args:["liop_runtime"],env:this.config.allowEnv?{...R(),RUNTIME_ID:this.sandboxId}:{NODE_ENV:"production",LIOP_NODE:"true",RUNTIME_ID:this.sandboxId},preopens:{"/sandbox":this.workingDir,...this.config.allowedDirectories},stdout:this.stdoutHandle.fd,stderr:this.stderrHandle.fd});}catch(r){throw new Error(`Sandbox Initialization Failed: ${r instanceof Error?r.message:"FS Error"}`)}}async execute(r,o=[],d={}){let n=performance.now();if(r instanceof Buffer)try{let e=await WebAssembly.compile(new Uint8Array(r));w.analyze(e);let y=await WebAssembly.instantiate(e,this.wasi.getImportObject());this.wasi.start(y);let f=u.join(this.workingDir,"stdout.log"),p=u.join(this.workingDir,"stderr.log"),s=await i.readFile(f,"utf-8"),m=await i.readFile(p,"utf-8"),t=performance.now()-n;return {output:s||(m?`Error: ${m}`:"WASM_EXECUTION_SUCCESS"),fuelConsumed:Math.floor(t*1e3)}}catch(e){throw new Error(`WASM Runtime Error: ${e instanceof Error?e.message:String(e)}`)}else {let e=Object.create(null),y={records:o,...d};e.require=void 0,e.process=void 0,e.global=void 0,e.globalThis=void 0,e.Buffer=void 0,e.setTimeout=void 0,e.setInterval=void 0,e.setImmediate=void 0,e.queueMicrotask=void 0,e.eval=void 0,e.Function=void 0,e.SharedArrayBuffer=void 0,e.Date=void 0,e.ArrayBuffer=void 0,e.Uint8Array=void 0,e.Int8Array=void 0,e.Uint16Array=void 0,e.Int16Array=void 0,e.Uint32Array=void 0,e.Int32Array=void 0,e.Float32Array=void 0,e.Float64Array=void 0,e.BigInt64Array=void 0,e.BigUint64Array=void 0,e.DataView=void 0;let f=t=>{if(!t||typeof t!="object")return t;if(Array.isArray(t))return t.map(f);let a=Object.create(null);for(let[g,O]of Object.entries(t))a[g]=f(O);return a};e.records=f(JSON.parse(JSON.stringify(o))),e.env=f(JSON.parse(JSON.stringify(y)));for(let[t,a]of Object.entries(d))e[t]=f(JSON.parse(JSON.stringify(a)));let p=t=>{if(t&&typeof t=="object"&&!Object.isFrozen(t)){Object.freeze(t);for(let a of Object.keys(t))p(t[a]);}return t};p(e.records),p(e.env);for(let t of Object.keys(e))Object.defineProperty(e,t,{writable:false,configurable:false});let s=String(r);(/^\s*return\s/m.test(s)||!s.includes("function liop_main"))&&(s.includes("function liop_main")||(s=`function liop_main(env) {
|
|
2
|
+
${s}
|
|
3
|
+
}`));let m=`
|
|
4
|
+
(function() {
|
|
5
|
+
"use strict";
|
|
6
|
+
try {
|
|
7
|
+
// Pre-execution prototype freezing (PCI-DSS Compliance)
|
|
8
|
+
Object.freeze(Object.prototype);
|
|
9
|
+
Object.freeze(Array.prototype);
|
|
10
|
+
Object.freeze(String.prototype);
|
|
11
|
+
Object.freeze(Number.prototype);
|
|
12
|
+
Object.freeze(Boolean.prototype);
|
|
13
|
+
Object.freeze(RegExp.prototype);
|
|
14
|
+
Object.freeze(Map.prototype);
|
|
15
|
+
Object.freeze(Set.prototype);
|
|
16
|
+
Object.freeze(Promise.prototype);
|
|
17
|
+
Object.freeze(Error.prototype);
|
|
18
|
+
Object.freeze(Object.getPrototypeOf(function(){}));
|
|
19
|
+
|
|
20
|
+
${s}
|
|
21
|
+
if (typeof liop_main === 'function') {
|
|
22
|
+
return liop_main(env);
|
|
23
|
+
}
|
|
24
|
+
return "ERR_NO_ENTRY_POINT";
|
|
25
|
+
} catch(e) {
|
|
26
|
+
return "LogicError: " + e.message;
|
|
27
|
+
}
|
|
28
|
+
})();
|
|
29
|
+
`;try{let t=new E.Script(m,{filename:`liop-sandbox-${this.sandboxId.slice(0,8)}.js`});!process.env.VITEST&&typeof Object.prototype=="object"&&!Object.isFrozen(Object.prototype)&&(Object.freeze(Object.prototype),Object.freeze(Array.prototype),Object.freeze(String.prototype),Object.freeze(Number.prototype),Object.freeze(Boolean.prototype),Object.freeze(RegExp.prototype),Object.freeze(Map.prototype),Object.freeze(Set.prototype),Object.freeze(Promise.prototype),Object.freeze(Error.prototype));let a=E.createContext(e,{name:"LIOP Isolate",origin:"liop://sandbox",microtaskMode:"afterEvaluate"}),g=t.runInContext(a,{timeout:5e3,breakOnSigint:!0,displayErrors:!0}),O=performance.now()-n,A=Math.floor(O*1500+100),b=Math.ceil(A/100)*100;if(b>1e6)throw new Error("LIOP_RESOURCE_EXHAUSTED: Execution fuel limit exceeded.");return {output:g,fuelConsumed:b}}catch(t){throw new Error(`V8 Isolate Fault: ${t instanceof Error?t.message:"Execution Timeout"}`)}}}async teardown(){try{this.stdoutHandle&&await this.stdoutHandle.close(),this.stderrHandle&&await this.stderrHandle.close(),await i.rm(this.workingDir,{recursive:!0,force:!0});}catch{}}};
|
|
30
|
+
export{w as a,R as b,h as c};//# sourceMappingURL=chunk-RYYRR4N5.js.map
|
|
31
|
+
//# sourceMappingURL=chunk-RYYRR4N5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sandbox/guardian.ts","../src/sandbox/wasi.ts"],"names":["GuardianError","message","ASTGuardian","module","imports","_importCount","ALLOWED_WASI_FUNCTIONS","imp","originalEmit","name","data","args","getDefaultEnvironment","safeKeys","env","key","val","WasiSandbox","config","crypto","WASI","error","compiledLogic","records","inputs","startTime","instance","stdoutPath","stderrPath","stdout","stderr","duration","sandboxEnv","toNullPrototype","obj","clone","value","deepFreeze","processedLogic","scriptCode","script","vm","context","output","rawFuel","fuelUsed"],"mappings":"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","file":"chunk-RYYRR4N5.js","sourcesContent":["export class GuardianError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(`AST Sec-Policy Violation: ${message}`);\n\t\tthis.name = \"GuardianError\";\n\t}\n}\n\n/**\n * The Guardian-TS Module\n * Scans the Abstract Syntax Tree (AST) imports of incoming WASM\n * before it reaches the V8 Wasmtime engine to prevent sandbox-escape\n * zero-days, resource exhaustion bombs, and evasive execution.\n */\nexport const ASTGuardian = {\n\t/**\n\t * Analyzes the WebAssembly Module interface proactively.\n\t *\n\t * @param module - The compiled WebAssembly.Module to inspect\n\t * @throws {GuardianError} If illegal imports or capabilities are detected\n\t */\n\tanalyze(module: WebAssembly.Module): void {\n\t\tconst imports = WebAssembly.Module.imports(module);\n\t\tlet _importCount = 0;\n\n\t\tconst ALLOWED_WASI_FUNCTIONS = new Set([\n\t\t\t\"fd_write\",\n\t\t\t\"fd_read\",\n\t\t\t\"fd_close\",\n\t\t\t\"fd_seek\",\n\t\t\t\"environ_get\",\n\t\t\t\"environ_sizes_get\",\n\t\t\t\"args_get\",\n\t\t\t\"args_sizes_get\",\n\t\t\t\"clock_time_get\",\n\t\t\t\"random_get\",\n\t\t\t\"proc_exit\",\n\t\t\t\"fd_prestat_get\",\n\t\t\t\"fd_prestat_dir_name\",\n\t\t\t\"fd_fdstat_get\",\n\t\t]);\n\n\t\tfor (const imp of imports) {\n\t\t\t// Strict Sandbox Validation: Only allow WASI preview 1 specific whitelisted functions.\n\t\t\tif (imp.module === \"wasi_snapshot_preview1\") {\n\t\t\t\tif (!ALLOWED_WASI_FUNCTIONS.has(imp.name)) {\n\t\t\t\t\tthrow new GuardianError(\n\t\t\t\t\t\t`Banned WASI Import Detected: ${imp.module}/${imp.name}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new GuardianError(\n\t\t\t\t\t`Banned Host Import Module Detected: ${imp.module}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t_importCount++;\n\n\t\t\tif (_importCount > 128) {\n\t\t\t\tthrow new GuardianError(\n\t\t\t\t\t\"Import limit exceeded. Possible resource exhaustion attack.\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// In Node.js / V8, the maximum module size and function limits\n\t\t// are natively enforced by the engine during compilation.\n\t\t// A successfully compiled WebAssembly.Module already passed structural checks.\n\t},\n};\n","import crypto from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport vm from \"node:vm\";\nimport { WASI } from \"node:wasi\";\nimport { ASTGuardian } from \"./guardian.js\";\n\n// Silence Node.js ExperimentalWarning for WASI (Industrial console parity)\nconst originalEmit = process.emit;\n// @ts-expect-error\nprocess.emit = (name, data, ...args) => {\n\tif (\n\t\t(name === \"warning\" &&\n\t\t\ttypeof data === \"object\" &&\n\t\t\t(data as Record<string, unknown>).name === \"ExperimentalWarning\" &&\n\t\t\tString((data as Record<string, unknown>).message).includes(\"WASI\")) ||\n\t\tString((data as Record<string, unknown>).message).includes(\"importing WASI\")\n\t) {\n\t\treturn false;\n\t}\n\treturn originalEmit.call(process, name, data, ...args);\n};\n\n/**\n * Returns a filtered environment object containing only safe system variables,\n * preventing exposure of sensitive credentials and shell function injection.\n */\nexport function getDefaultEnvironment(): Record<string, string> {\n\tconst isWindows = process.platform === \"win32\";\n\tconst safeKeys = isWindows\n\t\t? [\n\t\t\t\t\"APPDATA\",\n\t\t\t\t\"HOMEDRIVE\",\n\t\t\t\t\"HOMEPATH\",\n\t\t\t\t\"LOCALAPPDATA\",\n\t\t\t\t\"PATH\",\n\t\t\t\t\"PROCESSOR_ARCHITECTURE\",\n\t\t\t\t\"SYSTEMDRIVE\",\n\t\t\t\t\"SYSTEMROOT\",\n\t\t\t\t\"TEMP\",\n\t\t\t\t\"USERNAME\",\n\t\t\t\t\"USERPROFILE\",\n\t\t\t\t\"PROGRAMFILES\",\n\t\t\t]\n\t\t: [\"HOME\", \"LOGNAME\", \"PATH\", \"SHELL\", \"TERM\", \"USER\"];\n\n\tconst env: Record<string, string> = {\n\t\tNODE_ENV: \"production\",\n\t\tLIOP_NODE: \"true\",\n\t};\n\n\tfor (const key of safeKeys) {\n\t\tconst val = process.env[key];\n\t\tif (val !== undefined && !val.startsWith(\"()\")) {\n\t\t\tenv[key] = val;\n\t\t}\n\t}\n\n\treturn env;\n}\n\nexport interface SandboxConfig {\n\tallowEnv?: boolean;\n\tallowedDirectories?: Record<string, string>; // guestPath -> hostPath\n\tmemoryLimitMb?: number;\n}\n\n/**\n * LIOP WasiSandbox (Industrial Grade)\n *\n * Provides a production-grade isolated environment for executing untrusted logic.\n * Primarily uses WebAssembly (WASI) for byte-code isolation, with a hardened\n * V8 Isolate fallback for dynamic JS-to-WASM logic injection.\n */\nexport class WasiSandbox {\n\tprivate wasi!: WASI;\n\tprivate sandboxId: string;\n\tprivate workingDir: string;\n\tprivate config: SandboxConfig;\n\tprivate stdoutHandle: fs.FileHandle | null = null;\n\tprivate stderrHandle: fs.FileHandle | null = null;\n\n\tconstructor(config: SandboxConfig = {}) {\n\t\tthis.sandboxId = crypto.randomUUID();\n\t\t// Use a dedicated LIOP directory in the OS temp folder\n\t\tthis.workingDir = path.join(\n\t\t\tos.tmpdir(),\n\t\t\t\"liop-mesh\",\n\t\t\t\"sandboxes\",\n\t\t\tthis.sandboxId,\n\t\t);\n\t\tthis.config = config;\n\t}\n\n\t/**\n\t * Initializes the physical sandbox environment with strict directory lockdown.\n\t */\n\tpublic async init(): Promise<void> {\n\t\ttry {\n\t\t\tawait fs.mkdir(this.workingDir, { recursive: true });\n\n\t\t\t// Initialize WASI with explicit limits\n\t\t\tthis.stdoutHandle = await fs.open(\n\t\t\t\tpath.join(this.workingDir, \"stdout.log\"),\n\t\t\t\t\"w+\",\n\t\t\t);\n\t\t\tthis.stderrHandle = await fs.open(\n\t\t\t\tpath.join(this.workingDir, \"stderr.log\"),\n\t\t\t\t\"w+\",\n\t\t\t);\n\n\t\t\tthis.wasi = new WASI({\n\t\t\t\tversion: \"preview1\",\n\t\t\t\targs: [\"liop_runtime\"],\n\t\t\t\tenv: this.config.allowEnv\n\t\t\t\t\t? { ...getDefaultEnvironment(), RUNTIME_ID: this.sandboxId }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tNODE_ENV: \"production\",\n\t\t\t\t\t\t\tLIOP_NODE: \"true\",\n\t\t\t\t\t\t\tRUNTIME_ID: this.sandboxId,\n\t\t\t\t\t\t},\n\t\t\t\tpreopens: {\n\t\t\t\t\t\"/sandbox\": this.workingDir,\n\t\t\t\t\t...this.config.allowedDirectories,\n\t\t\t\t},\n\t\t\t\tstdout: this.stdoutHandle.fd,\n\t\t\t\tstderr: this.stderrHandle.fd,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Sandbox Initialization Failed: ${error instanceof Error ? error.message : \"FS Error\"}`,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Executes logic (WASM or JS-Wrapped) with hard resource limits.\n\t */\n\tpublic async execute(\n\t\tcompiledLogic: Buffer | string,\n\t\trecords: Record<string, unknown>[] = [],\n\t\tinputs: Record<string, unknown> = {},\n\t): Promise<{ output: unknown; fuelConsumed: number }> {\n\t\tconst startTime = performance.now();\n\n\t\tif (compiledLogic instanceof Buffer) {\n\t\t\t// Path A: Native WebAssembly Isolation\n\t\t\ttry {\n\t\t\t\tconst module = await WebAssembly.compile(new Uint8Array(compiledLogic));\n\n\t\t\t\t// Tier-0 Guardian: Static analysis to prevent sandbox escapes\n\t\t\t\tASTGuardian.analyze(module);\n\n\t\t\t\tconst instance = await WebAssembly.instantiate(\n\t\t\t\t\tmodule,\n\t\t\t\t\tthis.wasi.getImportObject() as WebAssembly.Imports,\n\t\t\t\t);\n\n\t\t\t\t// Standard entry point\n\t\t\t\tthis.wasi.start(instance);\n\n\t\t\t\t// Capture output from the sandbox\n\t\t\t\tconst stdoutPath = path.join(this.workingDir, \"stdout.log\");\n\t\t\t\tconst stderrPath = path.join(this.workingDir, \"stderr.log\");\n\t\t\t\tconst stdout = await fs.readFile(stdoutPath, \"utf-8\");\n\t\t\t\tconst stderr = await fs.readFile(stderrPath, \"utf-8\");\n\n\t\t\t\tconst duration = performance.now() - startTime;\n\t\t\t\treturn {\n\t\t\t\t\toutput:\n\t\t\t\t\t\tstdout || (stderr ? `Error: ${stderr}` : \"WASM_EXECUTION_SUCCESS\"),\n\t\t\t\t\tfuelConsumed: Math.floor(duration * 1000),\n\t\t\t\t};\n\t\t\t} catch (error: unknown) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`WASM Runtime Error: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// Path B: Hardened V8 Isolate Fallback\n\t\t\t// Uses node:vm with zero-prototype objects to prevent prototype pollution escapes.\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: Required for Sandbox global poisoning\n\t\t\tconst sandboxEnv: any = Object.create(null); // Isolated global object\n\t\t\tconst env = { records, ...inputs };\n\n\t\t\t// Explicitly poison Node.js escape vectors in the context\n\t\t\tsandboxEnv.require = undefined;\n\t\t\tsandboxEnv.process = undefined;\n\t\t\tsandboxEnv.global = undefined;\n\t\t\tsandboxEnv.globalThis = undefined;\n\t\t\tsandboxEnv.Buffer = undefined;\n\t\t\tsandboxEnv.setTimeout = undefined;\n\t\t\tsandboxEnv.setInterval = undefined;\n\t\t\tsandboxEnv.setImmediate = undefined;\n\t\t\tsandboxEnv.queueMicrotask = undefined;\n\t\t\tsandboxEnv.eval = undefined;\n\t\t\tsandboxEnv.Function = undefined;\n\t\t\tsandboxEnv.SharedArrayBuffer = undefined;\n\t\t\tsandboxEnv.Date = undefined;\n\n\t\t\t// [DoS Defense] Block off-heap memory allocation vectors.\n\t\t\t// Logic-on-Origin operates on JSON data (env.records) — binary buffers\n\t\t\t// serve no legitimate purpose and enable memory exhaustion DoS.\n\t\t\t// (Uint8Array(2GB) bypassed Piscina's maxOldGenerationSizeMb limit)\n\t\t\tsandboxEnv.ArrayBuffer = undefined;\n\t\t\tsandboxEnv.Uint8Array = undefined;\n\t\t\tsandboxEnv.Int8Array = undefined;\n\t\t\tsandboxEnv.Uint16Array = undefined;\n\t\t\tsandboxEnv.Int16Array = undefined;\n\t\t\tsandboxEnv.Uint32Array = undefined;\n\t\t\tsandboxEnv.Int32Array = undefined;\n\t\t\tsandboxEnv.Float32Array = undefined;\n\t\t\tsandboxEnv.Float64Array = undefined;\n\t\t\tsandboxEnv.BigInt64Array = undefined;\n\t\t\tsandboxEnv.BigUint64Array = undefined;\n\t\t\tsandboxEnv.DataView = undefined;\n\n\t\t\t// Recurse and strip prototype chain from host-passed objects to prevent escaping via constructor\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: Required for recursive null prototype mapping\n\t\t\tconst toNullPrototype = (obj: any): any => {\n\t\t\t\tif (!obj || typeof obj !== \"object\") {\n\t\t\t\t\treturn obj;\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(obj)) {\n\t\t\t\t\treturn obj.map(toNullPrototype);\n\t\t\t\t}\n\t\t\t\tconst clone = Object.create(null);\n\t\t\t\tfor (const [key, val] of Object.entries(obj)) {\n\t\t\t\t\tclone[key] = toNullPrototype(val);\n\t\t\t\t}\n\t\t\t\treturn clone;\n\t\t\t};\n\n\t\t\t// Inject strictly monitored globals\n\t\t\tsandboxEnv.records = toNullPrototype(JSON.parse(JSON.stringify(records))); // Deep copy safety + null prototype\n\t\t\tsandboxEnv.env = toNullPrototype(JSON.parse(JSON.stringify(env)));\n\n\t\t\tfor (const [key, value] of Object.entries(inputs)) {\n\t\t\t\tsandboxEnv[key] = toNullPrototype(JSON.parse(JSON.stringify(value)));\n\t\t\t}\n\n\t\t\t// Freeze the sandbox context to prevent mutation (SEC-GAP-1)\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: Required for recursive deep freeze of unknown data\n\t\t\tconst deepFreeze = (obj: any) => {\n\t\t\t\tif (obj && typeof obj === \"object\" && !Object.isFrozen(obj)) {\n\t\t\t\t\tObject.freeze(obj);\n\t\t\t\t\tfor (const key of Object.keys(obj)) {\n\t\t\t\t\t\tdeepFreeze(obj[key]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn obj;\n\t\t\t};\n\n\t\t\tdeepFreeze(sandboxEnv.records);\n\t\t\tdeepFreeze(sandboxEnv.env);\n\n\t\t\t// Prevent property addition/modification on global scope\n\t\t\tfor (const key of Object.keys(sandboxEnv)) {\n\t\t\t\tObject.defineProperty(sandboxEnv, key, {\n\t\t\t\t\twritable: false,\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// LIOP Execution Wrapper\n\t\t\t// Host-side logic transformation to avoid 'new Function' in sandbox\n\t\t\tlet processedLogic = String(compiledLogic);\n\t\t\tif (\n\t\t\t\t/^\\s*return\\s/m.test(processedLogic) ||\n\t\t\t\t!processedLogic.includes(\"function liop_main\")\n\t\t\t) {\n\t\t\t\tif (!processedLogic.includes(\"function liop_main\")) {\n\t\t\t\t\tprocessedLogic = `function liop_main(env) {\\n${processedLogic}\\n}`;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst scriptCode = `\n\t\t\t\t(function() {\n\t\t\t\t\t\"use strict\";\n\t\t\t\t\ttry {\n\t\t\t\t\t\t// Pre-execution prototype freezing (PCI-DSS Compliance)\n\t\t\t\t\t\tObject.freeze(Object.prototype);\n\t\t\t\t\t\tObject.freeze(Array.prototype);\n\t\t\t\t\t\tObject.freeze(String.prototype);\n\t\t\t\t\t\tObject.freeze(Number.prototype);\n\t\t\t\t\t\tObject.freeze(Boolean.prototype);\n\t\t\t\t\t\tObject.freeze(RegExp.prototype);\n\t\t\t\t\t\tObject.freeze(Map.prototype);\n\t\t\t\t\t\tObject.freeze(Set.prototype);\n\t\t\t\t\t\tObject.freeze(Promise.prototype);\n\t\t\t\t\t\tObject.freeze(Error.prototype);\n\t\t\t\t\t\tObject.freeze(Object.getPrototypeOf(function(){}));\n\n\t\t\t\t\t\t${processedLogic}\n\t\t\t\t\t\tif (typeof liop_main === 'function') {\n\t\t\t\t\t\t\treturn liop_main(env);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn \"ERR_NO_ENTRY_POINT\";\n\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\treturn \"LogicError: \" + e.message;\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t`;\n\n\t\t\ttry {\n\t\t\t\tconst script = new vm.Script(scriptCode, {\n\t\t\t\t\tfilename: `liop-sandbox-${this.sandboxId.slice(0, 8)}.js`,\n\t\t\t\t});\n\n\t\t\t\t// Freeze Host prototypes in production (non-test environments) to completely block Prototype Pollution\n\t\t\t\tif (\n\t\t\t\t\t!process.env.VITEST &&\n\t\t\t\t\ttypeof Object.prototype === \"object\" &&\n\t\t\t\t\t!Object.isFrozen(Object.prototype)\n\t\t\t\t) {\n\t\t\t\t\tObject.freeze(Object.prototype);\n\t\t\t\t\tObject.freeze(Array.prototype);\n\t\t\t\t\tObject.freeze(String.prototype);\n\t\t\t\t\tObject.freeze(Number.prototype);\n\t\t\t\t\tObject.freeze(Boolean.prototype);\n\t\t\t\t\tObject.freeze(RegExp.prototype);\n\t\t\t\t\tObject.freeze(Map.prototype);\n\t\t\t\t\tObject.freeze(Set.prototype);\n\t\t\t\t\tObject.freeze(Promise.prototype);\n\t\t\t\t\tObject.freeze(Error.prototype);\n\t\t\t\t}\n\n\t\t\t\t// microtaskMode: Ensures Promises created inside the sandbox are\n\t\t\t\t// resolved within the timeout/breakOnSigint scope (Node.js ≥14.6).\n\t\t\t\t// Without this, async microtasks could escape the 5s CPU limit.\n\t\t\t\tconst context = vm.createContext(sandboxEnv, {\n\t\t\t\t\tname: \"LIOP Isolate\",\n\t\t\t\t\torigin: \"liop://sandbox\",\n\t\t\t\t\tmicrotaskMode: \"afterEvaluate\",\n\t\t\t\t});\n\n\t\t\t\t// Execution with hard CPU and Memory limits (Fuel)\n\t\t\t\tconst output = script.runInContext(context, {\n\t\t\t\t\ttimeout: 5000,\n\t\t\t\t\tbreakOnSigint: true,\n\t\t\t\t\tdisplayErrors: true,\n\t\t\t\t});\n\n\t\t\t\tconst duration = performance.now() - startTime;\n\t\t\t\t// SEC: Normalize fuel to buckets of 100 to prevent timing side-channel inference\n\t\t\t\tconst rawFuel = Math.floor(duration * 1500 + 100);\n\t\t\t\tconst fuelUsed = Math.ceil(rawFuel / 100) * 100;\n\n\t\t\t\tif (fuelUsed > 1000000) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"LIOP_RESOURCE_EXHAUSTED: Execution fuel limit exceeded.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn { output, fuelConsumed: fuelUsed };\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`V8 Isolate Fault: ${error instanceof Error ? error.message : \"Execution Timeout\"}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Physically cleans up the sandbox and releases resources.\n\t */\n\tpublic async teardown(): Promise<void> {\n\t\ttry {\n\t\t\tif (this.stdoutHandle) await this.stdoutHandle.close();\n\t\t\tif (this.stderrHandle) await this.stderrHandle.close();\n\t\t\tawait fs.rm(this.workingDir, { recursive: true, force: true });\n\t\t} catch (_e) {\n\t\t\t// Silent fail on teardown to prevent process crashes\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var a={initialize:[],"notifications/initialized":[],"notifications/cancelled":[],ping:[],"tools/list":["liop:tools:list"],"tools/call":["liop:tools:call"],"resources/list":["liop:resources:read"],"resources/read":["liop:resources:read"],"prompts/list":["liop:schema:read"],"prompts/get":["liop:schema:read"]};function d(e,t,l){let o=a[e];if(o!==void 0&&o.length===0)return {allowed:true};if(!t)return {allowed:false,reason:`Authentication required for method: ${e}`};let s=[...o??[],...l??[]];if(s.length===0)return {allowed:false,reason:`Unknown method: ${e}. Access denied (fail-closed).`};let n=new Set(t.scopes),i=s.filter(r=>!n.has(r));return i.length>0?{allowed:false,reason:`Insufficient scopes for ${e}. Missing: ${i.join(", ")}`}:{allowed:true}}var u=["liop:tools:list","liop:tools:call","liop:resources:read","liop:schema:read","liop:mesh:query"];export{d as a,u as b};//# sourceMappingURL=chunk-SB5XJXKV.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-SB5XJXKV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security/rbac.ts"],"names":["SCOPE_MAP","authorizeRequest","method","auth","additionalScopes","methodScopes","needed","clientScopes","missing","s","LIOP_SCOPES"],"mappings":"AAiBA,IAAMA,CAAAA,CAAyD,CAE9D,UAAA,CAAY,GACZ,2BAAA,CAA6B,EAAC,CAC9B,yBAAA,CAA2B,EAAC,CAC5B,IAAA,CAAM,GAGN,YAAA,CAAc,CAAC,iBAAiB,CAAA,CAChC,YAAA,CAAc,CAAC,iBAAiB,CAAA,CAGhC,iBAAkB,CAAC,qBAAqB,CAAA,CACxC,gBAAA,CAAkB,CAAC,qBAAqB,CAAA,CAGxC,cAAA,CAAgB,CAAC,kBAAkB,CAAA,CACnC,aAAA,CAAe,CAAC,kBAAkB,CACnC,CAAA,CAuBO,SAASC,CAAAA,CACfC,EACAC,CAAAA,CACAC,CAAAA,CACsB,CACtB,IAAMC,CAAAA,CAAeL,CAAAA,CAAUE,CAAM,CAAA,CAGrC,GAAIG,CAAAA,GAAiB,MAAA,EAAaA,CAAAA,CAAa,MAAA,GAAW,CAAA,CACzD,OAAO,CAAE,OAAA,CAAS,IAAK,CAAA,CAIxB,GAAI,CAACF,CAAAA,CACJ,OAAO,CACN,OAAA,CAAS,KAAA,CACT,MAAA,CAAQ,uCAAuCD,CAAM,CAAA,CACtD,CAAA,CAID,IAAMI,CAAAA,CAAS,CAAC,GAAID,CAAAA,EAAgB,EAAC,CAAI,GAAID,CAAAA,EAAoB,EAAG,CAAA,CAGpE,GAAIE,CAAAA,CAAO,SAAW,CAAA,CACrB,OAAO,CACN,OAAA,CAAS,KAAA,CACT,MAAA,CAAQ,CAAA,gBAAA,EAAmBJ,CAAM,gCAClC,CAAA,CAID,IAAMK,CAAAA,CAAe,IAAI,IAAIJ,CAAAA,CAAK,MAAM,CAAA,CAClCK,CAAAA,CAAUF,EAAO,MAAA,CAAQG,CAAAA,EAAM,CAACF,CAAAA,CAAa,GAAA,CAAIE,CAAC,CAAC,CAAA,CAEzD,OAAID,CAAAA,CAAQ,MAAA,CAAS,CAAA,CACb,CACN,OAAA,CAAS,KAAA,CACT,MAAA,CAAQ,CAAA,wBAAA,EAA2BN,CAAM,CAAA,WAAA,EAAcM,CAAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CAC1E,CAAA,CAGM,CAAE,QAAS,IAAK,CACxB,CAMO,IAAME,EAAc,CAC1B,iBAAA,CACA,iBAAA,CACA,qBAAA,CACA,mBACA,iBACD","file":"chunk-SB5XJXKV.js","sourcesContent":["/**\n * LIOP RBAC Engine — Scope-Based Authorization\n *\n * Maps MCP JSON-RPC methods to required LIOP OAuth scopes.\n * Enforces least-privilege access at the router level before\n * any tool execution or resource read occurs.\n *\n * Standards: NIST SP 800-207 §4.3 (least privilege), OWASP LLM06 (Excessive Agency),\n * OWASP API-A01 (Broken Access Control)\n */\n\nimport type { AuthInfo } from \"./jwt-validator.js\";\n\n/**\n * Maps MCP JSON-RPC methods to the LIOP scopes required to invoke them.\n * Empty array = no authentication required (public endpoints).\n */\nconst SCOPE_MAP: Readonly<Record<string, readonly string[]>> = {\n\t// Protocol lifecycle — unauthenticated (MCP spec compliance)\n\tinitialize: [],\n\t\"notifications/initialized\": [],\n\t\"notifications/cancelled\": [],\n\tping: [],\n\n\t// Tool operations — require explicit authorization\n\t\"tools/list\": [\"liop:tools:list\"],\n\t\"tools/call\": [\"liop:tools:call\"],\n\n\t// Resource operations — read-level access\n\t\"resources/list\": [\"liop:resources:read\"],\n\t\"resources/read\": [\"liop:resources:read\"],\n\n\t// Prompt/schema operations — schema-level access\n\t\"prompts/list\": [\"liop:schema:read\"],\n\t\"prompts/get\": [\"liop:schema:read\"],\n};\n\n/**\n * Authorization result with optional denial reason for audit logging.\n */\nexport interface AuthorizationResult {\n\tallowed: boolean;\n\treason?: string;\n}\n\n/**\n * Evaluates whether a request is authorized based on JWT scopes.\n *\n * Decision logic:\n * 1. Methods with no required scopes (initialize, ping) → always allowed.\n * 2. Methods with required scopes but no auth → denied.\n * 3. Methods with required scopes → all scopes must be present in the JWT.\n * 4. Unknown methods with no auth → denied (fail-closed per NIST SP 800-207).\n *\n * @param method - MCP JSON-RPC method name (e.g., \"tools/call\")\n * @param auth - Validated JWT context, or null if unauthenticated\n * @param additionalScopes - Extra scopes required by specific node configuration\n */\nexport function authorizeRequest(\n\tmethod: string,\n\tauth: AuthInfo | null,\n\tadditionalScopes?: readonly string[],\n): AuthorizationResult {\n\tconst methodScopes = SCOPE_MAP[method];\n\n\t// Methods explicitly marked as public (empty scope array) pass freely\n\tif (methodScopes !== undefined && methodScopes.length === 0) {\n\t\treturn { allowed: true };\n\t}\n\n\t// If no auth context and method requires scopes → deny\n\tif (!auth) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Authentication required for method: ${method}`,\n\t\t};\n\t}\n\n\t// Merge method-level scopes with node-level additional scopes\n\tconst needed = [...(methodScopes ?? []), ...(additionalScopes ?? [])];\n\n\t// If no scopes needed (unknown method, no additional) → fail-closed\n\tif (needed.length === 0) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Unknown method: ${method}. Access denied (fail-closed).`,\n\t\t};\n\t}\n\n\t// Verify all required scopes are present in the JWT\n\tconst clientScopes = new Set(auth.scopes);\n\tconst missing = needed.filter((s) => !clientScopes.has(s));\n\n\tif (missing.length > 0) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Insufficient scopes for ${method}. Missing: ${missing.join(\", \")}`,\n\t\t};\n\t}\n\n\treturn { allowed: true };\n}\n\n/**\n * All LIOP OAuth scopes supported by the protocol.\n * Used for PRM metadata and client registration.\n */\nexport const LIOP_SCOPES = [\n\t\"liop:tools:list\",\n\t\"liop:tools:call\",\n\t\"liop:resources:read\",\n\t\"liop:schema:read\",\n\t\"liop:mesh:query\",\n] as const;\n\nexport type LiopScope = (typeof LIOP_SCOPES)[number];\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {b}from'./chunk-2MGFSIXN.js';var o=b.object({name:b.string(),description:b.string().optional(),inputSchema:b.record(b.string(),b.unknown())}),i=b.object({uri:b.string(),name:b.string(),description:b.string().optional(),mimeType:b.string().optional()}),s=b.object({name:b.string(),description:b.string().optional(),arguments:b.array(b.object({name:b.string(),description:b.string().optional(),required:b.boolean().optional()})).optional()});export{o as a,i as b,s as c};//# sourceMappingURL=chunk-
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
1
|
+
import {b}from'./chunk-2MGFSIXN.js';var o=b.object({name:b.string(),description:b.string().optional(),inputSchema:b.record(b.string(),b.unknown())}),i=b.object({uri:b.string(),name:b.string(),description:b.string().optional(),mimeType:b.string().optional()}),s=b.object({name:b.string(),description:b.string().optional(),arguments:b.array(b.object({name:b.string(),description:b.string().optional(),required:b.boolean().optional()})).optional()});export{o as a,i as b,s as c};//# sourceMappingURL=chunk-TYVG6TXQ.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-TYVG6TXQ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"names":["ToolSchema","external_exports","ResourceSchema","PromptSchema"],"mappings":"oCAMO,IAAMA,CAAAA,CAAaC,EAAE,MAAA,CAAO,CAClC,KAAMA,CAAAA,CAAE,MAAA,GACR,WAAA,CAAaA,CAAAA,CAAE,QAAO,CAAE,QAAA,GACxB,WAAA,CAAaA,CAAAA,CAAE,OAAOA,CAAAA,CAAE,MAAA,GAAUA,CAAAA,CAAE,OAAA,EAAS,CAC9C,CAAC,EAIYC,CAAAA,CAAiBD,CAAAA,CAAE,OAAO,CACtC,GAAA,CAAKA,EAAE,MAAA,EAAO,CACd,KAAMA,CAAAA,CAAE,MAAA,GACR,WAAA,CAAaA,CAAAA,CAAE,QAAO,CAAE,QAAA,GACxB,QAAA,CAAUA,CAAAA,CAAE,QAAO,CAAE,QAAA,EACtB,CAAC,CAAA,CAIYE,EAAeF,CAAAA,CAAE,MAAA,CAAO,CACpC,IAAA,CAAMA,CAAAA,CAAE,QAAO,CACf,WAAA,CAAaA,EAAE,MAAA,EAAO,CAAE,UAAS,CACjC,SAAA,CAAWA,EACT,KAAA,CACAA,CAAAA,CAAE,OAAO,CACR,IAAA,CAAMA,EAAE,MAAA,EAAO,CACf,YAAaA,CAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CACjC,SAAUA,CAAAA,CAAE,OAAA,GAAU,QAAA,EACvB,CAAC,CACF,CAAA,CACC,QAAA,EACH,CAAC","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"names":["ToolSchema","external_exports","ResourceSchema","PromptSchema"],"mappings":"oCAMO,IAAMA,CAAAA,CAAaC,EAAE,MAAA,CAAO,CAClC,KAAMA,CAAAA,CAAE,MAAA,GACR,WAAA,CAAaA,CAAAA,CAAE,QAAO,CAAE,QAAA,GACxB,WAAA,CAAaA,CAAAA,CAAE,OAAOA,CAAAA,CAAE,MAAA,GAAUA,CAAAA,CAAE,OAAA,EAAS,CAC9C,CAAC,EAIYC,CAAAA,CAAiBD,CAAAA,CAAE,OAAO,CACtC,GAAA,CAAKA,EAAE,MAAA,EAAO,CACd,KAAMA,CAAAA,CAAE,MAAA,GACR,WAAA,CAAaA,CAAAA,CAAE,QAAO,CAAE,QAAA,GACxB,QAAA,CAAUA,CAAAA,CAAE,QAAO,CAAE,QAAA,EACtB,CAAC,CAAA,CAIYE,EAAeF,CAAAA,CAAE,MAAA,CAAO,CACpC,IAAA,CAAMA,CAAAA,CAAE,QAAO,CACf,WAAA,CAAaA,EAAE,MAAA,EAAO,CAAE,UAAS,CACjC,SAAA,CAAWA,EACT,KAAA,CACAA,CAAAA,CAAE,OAAO,CACR,IAAA,CAAMA,EAAE,MAAA,EAAO,CACf,YAAaA,CAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CACjC,SAAUA,CAAAA,CAAE,OAAA,GAAU,QAAA,EACvB,CAAC,CACF,CAAA,CACC,QAAA,EACH,CAAC","file":"chunk-TYVG6TXQ.js","sourcesContent":["import { z } from \"zod\";\n\n/**\n * Base Protocol Types representing parity with Model Context Protocol\n */\n\nexport const ToolSchema = z.object({\n\tname: z.string(),\n\tdescription: z.string().optional(),\n\tinputSchema: z.record(z.string(), z.unknown()), // Represents a JSON Schema\n});\n\nexport type Tool = z.infer<typeof ToolSchema>;\n\nexport const ResourceSchema = z.object({\n\turi: z.string(),\n\tname: z.string(),\n\tdescription: z.string().optional(),\n\tmimeType: z.string().optional(),\n});\n\nexport type Resource = z.infer<typeof ResourceSchema>;\n\nexport const PromptSchema = z.object({\n\tname: z.string(),\n\tdescription: z.string().optional(),\n\targuments: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tname: z.string(),\n\t\t\t\tdescription: z.string().optional(),\n\t\t\t\trequired: z.boolean().optional(),\n\t\t\t}),\n\t\t)\n\t\t.optional(),\n});\n\nexport type Prompt = z.infer<typeof PromptSchema>;\n\nexport interface CallToolRequest {\n\tname: string;\n\targuments?: Record<string, unknown>;\n}\n\nexport interface CallToolResult {\n\tcontent: Array<{\n\t\ttype: \"text\" | \"image\" | \"resource\";\n\t\ttext?: string;\n\t\tdata?: string;\n\t\tmimeType?: string;\n\t\tresource?: {\n\t\t\turi: string;\n\t\t\ttext?: string;\n\t\t\tblob?: string;\n\t\t};\n\t}>;\n\tisError?: boolean;\n}\n\nexport interface GetPromptRequest {\n\tname: string;\n\targuments?: Record<string, string>;\n}\n\nexport interface GetPromptResult {\n\tdescription?: string;\n\tmessages: Array<{\n\t\trole: \"user\" | \"assistant\";\n\t\tcontent:\n\t\t\t| { type: \"text\"; text: string }\n\t\t\t| { type: \"image\"; data: string; mimeType: string }\n\t\t\t| {\n\t\t\t\t\ttype: \"resource\";\n\t\t\t\t\tresource: { uri: string; text?: string; blob?: string };\n\t\t\t };\n\t}>;\n}\n\nexport interface ServerInfo {\n\tname: string;\n\tversion: string;\n\tcapabilities?: {\n\t\tprompts?: { listChanged?: boolean };\n\t\tresources?: { subscribe?: boolean; listChanged?: boolean };\n\t\ttools?: { listChanged?: boolean };\n\t\tlogging?: Record<string, unknown>;\n\t};\n}\n\nexport interface McpRequest {\n\tmethod: string;\n\tparams?: unknown;\n\tid?: string | number | null;\n\tjsonrpc?: \"2.0\";\n}\n\nexport interface McpResponse {\n\tjsonrpc: \"2.0\";\n\tid?: string | number | null;\n\tresult?: unknown;\n\terror?: {\n\t\tcode: number;\n\t\tmessage: string;\n\t\tdata?: unknown;\n\t};\n}\n\n/**\n * Re-export AuthInfo from the security module for convenience.\n * Compatible with MCP TypeScript SDK AuthInfo interface shape.\n */\nexport type { AuthInfo } from \"./security/jwt-validator.js\";\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {a as a$1}from'./chunk-SW53FNSN.js';import {a as a$4}from'./chunk-DBXGYHKY.js';import {a as a$2}from'./chunk-SB5XJXKV.js';import {a as a$3,c}from'./chunk-V5MKJT6S.js';import {a}from'./chunk-S6RJHZV2.js';import*as K from'crypto';import*as ce from'@grpc/grpc-js';var W=class{name="o200k_base";countFn;constructor(e,t){this.countFn=e,t&&t(1e4);}countTokens(e){return e.length===0?0:this.countFn(e)}},B=class{name="heuristic (chars/4)";countTokens(e){return e.length===0?0:Math.ceil(e.length/4)}};async function fe(){try{let c=await import('gpt-tokenizer'),e=new W(c.countTokens,c.setMergeCacheSize);return a.debug("[LIOP-Economy] Token estimator initialized: o200k_base"),e}catch{return a.info("[LIOP-Economy] gpt-tokenizer unavailable, falling back to heuristic estimator"),new B}}function he(){return new B}var N="1.9.1";var ge=/^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;function Ee(c){let e=new Set([c]),t=new Set,r=c.match(ge);if(!r)return ()=>false;let n={major:+r[1],minor:+r[2],patch:+r[3],prerelease:r[4]};if(n.prerelease!=null)return function(a){return a===c};function i(s){return t.add(s),false}function o(s){return e.add(s),true}return function(a){if(e.has(a))return true;if(t.has(a))return false;let l=a.match(ge);if(!l)return i(a);let u={major:+l[1],minor:+l[2],patch:+l[3],prerelease:l[4]};return u.prerelease!=null||n.major!==u.major?i(a):n.major===0?n.minor===u.minor&&n.patch<=u.patch?o(a):i(a):n.minor<=u.minor?o(a):i(a)}}var Te=Ee(N);var ke=N.split(".")[0],$=Symbol.for(`opentelemetry.js.api.${ke}`),A=typeof globalThis=="object"?globalThis:typeof self=="object"?self:typeof window=="object"?window:typeof global=="object"?global:{};function V(c,e,t,r=false){var n;let i=A[$]=(n=A[$])!==null&&n!==void 0?n:{version:N};if(!r&&i[c]){let o=new Error(`@opentelemetry/api: Attempted duplicate registration of API: ${c}`);return t.error(o.stack||o.message),false}if(i.version!==N){let o=new Error(`@opentelemetry/api: Registration of version v${i.version} for ${c} does not match previously registered API v${N}`);return t.error(o.stack||o.message),false}return i[c]=e,t.debug(`@opentelemetry/api: Registered a global for ${c} v${N}.`),true}function b(c){var e,t;let r=(e=A[$])===null||e===void 0?void 0:e.version;if(!(!r||!Te(r)))return (t=A[$])===null||t===void 0?void 0:t[c]}function F(c,e){e.debug(`@opentelemetry/api: Unregistering a global for ${c} v${N}.`);let t=A[$];t&&delete t[c];}var z=class{constructor(e){this._namespace=e.namespace||"DiagComponentLogger";}debug(...e){return x("debug",this._namespace,e)}error(...e){return x("error",this._namespace,e)}info(...e){return x("info",this._namespace,e)}warn(...e){return x("warn",this._namespace,e)}verbose(...e){return x("verbose",this._namespace,e)}};function x(c,e,t){let r=b("diag");if(r)return r[c](e,...t)}var v;(function(c){c[c.NONE=0]="NONE",c[c.ERROR=30]="ERROR",c[c.WARN=50]="WARN",c[c.INFO=60]="INFO",c[c.DEBUG=70]="DEBUG",c[c.VERBOSE=80]="VERBOSE",c[c.ALL=9999]="ALL";})(v||(v={}));function ye(c,e){c<v.NONE?c=v.NONE:c>v.ALL&&(c=v.ALL),e=e||{};function t(r,n){let i=e[r];return typeof i=="function"&&c>=n?i.bind(e):function(){}}return {error:t("error",v.ERROR),warn:t("warn",v.WARN),info:t("info",v.INFO),debug:t("debug",v.DEBUG),verbose:t("verbose",v.VERBOSE)}}var Se="diag",D=class c{static instance(){return this._instance||(this._instance=new c),this._instance}constructor(){function e(n){return function(...i){let o=b("diag");if(o)return o[n](...i)}}let t=this,r=(n,i={logLevel:v.INFO})=>{var o,s,a;if(n===t){let p=new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");return t.error((o=p.stack)!==null&&o!==void 0?o:p.message),false}typeof i=="number"&&(i={logLevel:i});let l=b("diag"),u=ye((s=i.logLevel)!==null&&s!==void 0?s:v.INFO,n);if(l&&!i.suppressOverrideMessage){let p=(a=new Error().stack)!==null&&a!==void 0?a:"<failed to generate stacktrace>";l.warn(`Current logger will be overwritten from ${p}`),u.warn(`Current logger will overwrite one already registered from ${p}`);}return V("diag",u,t,true)};t.setLogger=r,t.disable=()=>{F(Se,t);},t.createComponentLogger=n=>new z(n),t.verbose=e("verbose"),t.debug=e("debug"),t.info=e("info"),t.warn=e("warn"),t.error=e("error");}};var J=class{constructor(){}createGauge(e,t){return Ne}createHistogram(e,t){return we}createCounter(e,t){return Re}createUpDownCounter(e,t){return be}createObservableGauge(e,t){return Le}createObservableCounter(e,t){return Ce}createObservableUpDownCounter(e,t){return Me}addBatchObservableCallback(e,t){}removeBatchObservableCallback(e){}},C=class{},Q=class extends C{add(e,t){}},Z=class extends C{add(e,t){}},X=class extends C{record(e,t){}},Y=class extends C{record(e,t){}},U=class{addCallback(e){}removeCallback(e){}},ee=class extends U{},te=class extends U{},oe=class extends U{},_e=new J,Re=new Q,Ne=new X,we=new Y,be=new Z,Ce=new ee,Le=new te,Me=new oe;var re=class{getMeter(e,t,r){return _e}},Oe=new re;var ne="metrics",G=class c{constructor(){}static getInstance(){return this._instance||(this._instance=new c),this._instance}setGlobalMeterProvider(e){return V(ne,e,D.instance())}getMeterProvider(){return b(ne)||Oe}getMeter(e,t,r){return this.getMeterProvider().getMeter(e,t,r)}disable(){F(ne,D.instance());}};var se=G.getInstance();var $e="@nekzus/liop",Ae="1.2.0-alpha.9",xe=[1,4,16,64,256,1024,4096,16384,65536,262144,1048576,4194304,16777216,67108864],De=[.01,.02,.04,.08,.16,.32,.64,1.28,2.56,5.12,10.24,20.48,40.96,81.92],H=class{tokenUsage;operationDuration;active=false;constructor(){try{let e=se.getMeter($e,Ae);this.tokenUsage=e.createHistogram("gen_ai.client.token.usage",{description:"Number of tokens used in LIOP Logic-on-Origin operations",unit:"{token}",advice:{explicitBucketBoundaries:xe}}),this.operationDuration=e.createHistogram("gen_ai.client.operation.duration",{description:"Duration of LIOP operations",unit:"s",advice:{explicitBucketBoundaries:De}}),this.active=!0,a.debug("[LIOP-OTel] gen_ai.* metrics bridge initialized");}catch(e){a.debug(`[LIOP-OTel] Bridge disabled: ${e instanceof Error?e.message:String(e)}`);let t={record:()=>{}};this.tokenUsage=t,this.operationDuration=t;}}recordTokens(e,t,r,n){this.tokenUsage.record(e,{"gen_ai.system":"liop","gen_ai.operation.name":r,"gen_ai.token.type":t,"gen_ai.request.model":"liop-mesh",...n?{"liop.tool.name":n}:{}});}recordDuration(e,t,r){this.operationDuration.record(e/1e3,{"gen_ai.system":"liop","gen_ai.operation.name":t,...r?{"error.type":r}:{}});}isActive(){return this.active}};var Ue={tools_list:"chat",tool_call:"execute_tool",resource_read:"chat",resource_list:"chat",prompt_get:"chat",prompt_list:"chat",diagnostic:"chat"},I=class c{static instance=null;operations=[];sessionId;startedAt;estimator;otelBridge;constructor(){this.sessionId=crypto.randomUUID(),this.startedAt=Date.now(),this.estimator=he(),this.otelBridge=new H,this.initRealEstimator();}initRealEstimator(){fe().then(e=>{this.estimator=e;}).catch(()=>{});}static getInstance(){return c.instance||(c.instance=new c),c.instance}countTokens(e){try{return this.estimator.countTokens(e)}catch{return Math.ceil(e.length/4)}}record(e){let t={...e,timestamp:Date.now()};this.operations.push(t);try{let r=Ue[e.type]||"chat";e.estimatedInputTokens>0&&this.otelBridge.recordTokens(e.estimatedInputTokens,"input",r,e.toolName),e.estimatedOutputTokens>0&&this.otelBridge.recordTokens(e.estimatedOutputTokens,"output",r,e.toolName),e.durationMs!==void 0&&this.otelBridge.recordDuration(e.durationMs,r);}catch{}}estimateTokens(e){return this.countTokens(e)}getReport(){return {sessionId:this.sessionId,operations:[...this.operations],totalInputTokens:this.operations.reduce((e,t)=>e+t.estimatedInputTokens,0),totalOutputTokens:this.operations.reduce((e,t)=>e+t.estimatedOutputTokens,0),estimatorName:this.estimator.name,sessionUptimeMs:Date.now()-this.startedAt}}getPerToolReport(){let e=new Map;for(let t of this.operations){let r=t.toolName||t.method,n=e.get(r)||{input:0,output:0,calls:0,avgDurationMs:0},i=n.avgDurationMs*n.calls+(t.durationMs||0),o=n.calls+1;e.set(r,{input:n.input+t.estimatedInputTokens,output:n.output+t.estimatedOutputTokens,calls:o,avgDurationMs:o>0?i/o:0});}return e}formatStatusBlock(){let e=this.getReport();if(e.operations.length===0)return "";let t=this.formatUptime(e.sessionUptimeMs),r=e.totalInputTokens+e.totalOutputTokens,n=new Map;for(let d of e.operations){let g=d.type,T=n.get(g)||{count:0,input:0,output:0};n.set(g,{count:T.count+1,input:T.input+d.estimatedInputTokens,output:T.output+d.estimatedOutputTokens});}let i=Array.from(n.entries()),o=i.map(([d,g],T)=>{let y=T===i.length-1?"\u2502 \u2514\u2500":"\u2502 \u251C\u2500",R=g.output>0?` / ${g.output.toLocaleString()} out`:"";return `${y} ${d} \xD7${g.count} \u2192 ${g.input.toLocaleString()} in${R}`}),s=this.getPerToolReport(),a=Array.from(s.entries()).filter(([d])=>d!=="tools/list"&&d!=="LiopMeshStatus"),l=[];a.length>0&&(l.push("\u251C\u2500 By Tool:"),a.forEach(([d,g],T)=>{let y=T===a.length-1?"\u2502 \u2514\u2500":"\u2502 \u251C\u2500",R=g.output>0?` / ${g.output.toLocaleString()} out`:"",k=g.avgDurationMs>0?` ~${Math.round(g.avgDurationMs)}ms`:"";l.push(`${y} ${d}: ${g.input.toLocaleString()} in${R} (\xD7${g.calls})${k}`);}));let u=e.operations.filter(d=>d.durationMs!==void 0),p=u.length>0?Math.round(u.reduce((d,g)=>d+(g.durationMs||0),0)/u.length):0,m=this.otelBridge.isActive()?"gen_ai.client.token.usage \u2192 active":"disabled";return [`
|
|
2
|
+
Token Economy:`,`\u251C\u2500 Session: ${e.sessionId.slice(0,8)} (${t})`,`\u251C\u2500 Estimator: ${e.estimatorName}`,`\u251C\u2500 Operations: ${e.operations.length}`,...o,`\u251C\u2500 Total: ${e.totalInputTokens.toLocaleString()} in / ${e.totalOutputTokens.toLocaleString()} out (${r.toLocaleString()} combined)`,...l,...p>0?[`\u251C\u2500 Avg Latency: ${p}ms`]:[],`\u2514\u2500 OTel: ${m}`].join(`
|
|
3
|
+
`)}formatUptime(e){let t=Math.floor(e/1e3);if(t<60)return `${t}s`;let r=Math.floor(t/60),n=t%60;if(r<60)return `${r}m ${n}s`;let i=Math.floor(r/60),o=r%60;return `${i}h ${o}m`}reset(){this.operations=[];}static destroy(){c.instance=null;}};function L(){let c=process.env.LIOP_MCP_COMPACT_TOOL_DESCRIPTIONS?.toLowerCase().trim();return !(c==="0"||c==="false"||c==="no")}function ie(c){let e=c,t=[`
|
|
4
|
+
|
|
5
|
+
[LIOP-PROTO-V1:`,`\r
|
|
6
|
+
\r
|
|
7
|
+
[LIOP-PROTO-V1:`,`
|
|
8
|
+
[LIOP-PROTO-V1:`];for(let r of t){let n=e.indexOf(r);if(n!==-1){e=e.slice(0,n);break}}return e.trimEnd()}var ve=300,ae=5,Ie=class c$1{constructor(e,t=null,r=50051){this.liopServer=e;this.meshNode=t;this.defaultRpcPort=r;this.meshNode&&(this.meshNode.registerManifestHandler(()=>{let n=this.liopServer.listTools().map(s=>({name:s.name,description:s.description,inputSchema:s.inputSchema})),i=this.liopServer.listResources().map(s=>({name:s.name,uri:s.uri,description:s.description,mimeType:s.mimeType})),o=this.liopServer.config;return {peerId:this.meshNode?.getPeerId()||"unknown",grpcPort:this.defaultRpcPort,tools:[...n],resources:i,serverInfo:this.liopServer.getServerInfo(),authRequired:this.liopServer.jwtValidator!==void 0,tokenSlug:o?.tokenSlug,taxonomy:o?.taxonomy?{domain:o.taxonomy.domain||"Unknown Domain",clearanceTier:o.taxonomy.clearanceTier??0,executionTypes:o.taxonomy.executionTypes||[]}:void 0}}),this.meshNode.announceManifest().catch(n=>{a.info(`[LIOP-Router] Failed to announce manifest: ${n instanceof Error?n.message:String(n)}`);})),process.env.LIOP_DIAGNOSTIC_LEVEL==="full"&&process.stderr.write(`\u26A0\uFE0F [LIOP-Security] Diagnostic level set to FULL \u2014 PeerIDs and network topology are exposed. Do NOT use in production.
|
|
9
|
+
`);}manifestCache=new Map;currentDiscovery=null;verifier=new a$1;onToolsChanged;manifestFailureState=new Map;static MANIFEST_FAILURE_BASE_COOLDOWN_MS=15e3;static MANIFEST_FAILURE_MAX_COOLDOWN_MS=5*6e4;static MANIFEST_SKIP_LOG_THROTTLE_MS=3e4;shouldSkipManifestQuery(e){let t=this.manifestFailureState.get(e);if(!t)return false;let r=Date.now();return r>=t.cooldownUntil?false:(r-t.lastSkipLogAt>c$1.MANIFEST_SKIP_LOG_THROTTLE_MS&&(a.info(`[LIOP-Router] Skipping manifest query for ${e} during cooldown (${Math.ceil((t.cooldownUntil-r)/1e3)}s remaining)`),t.lastSkipLogAt=r),true)}recordManifestQuerySuccess(e){this.manifestFailureState.delete(e);}recordManifestQueryFailure(e){let t=Date.now(),n=(this.manifestFailureState.get(e)?.failures||0)+1,i=Math.min(c$1.MANIFEST_FAILURE_BASE_COOLDOWN_MS*2**Math.max(0,n-1),c$1.MANIFEST_FAILURE_MAX_COOLDOWN_MS);this.manifestFailureState.set(e,{failures:n,cooldownUntil:t+i,lastSkipLogAt:0});}async dispatch(e,t){let{method:r,params:n,id:i}=e;if(a.info(`[LIOP-Router] Processing: ${r}`),this.liopServer.jwtValidator){let o=a$2(r,t??null);if(!o.allowed)return a.info(`[LIOP-Router] RBAC Access Denied for method '${r}': ${o.reason}`),{jsonrpc:"2.0",id:i,error:{code:-32099,message:o.reason||"Access Denied"}}}switch(r){case "initialize":return {jsonrpc:"2.0",id:i,result:{protocolVersion:"2025-11-25",capabilities:{tools:{listChanged:true},resources:{listChanged:true},prompts:{listChanged:true}},serverInfo:this.liopServer.getServerInfo()}};case "notifications/initialized":return this.kickDiscoveryAfterInitialized().catch(()=>{}),null;case "notifications/cancelled":return null;case "ping":return {jsonrpc:"2.0",id:i,result:{}};case "tools/list":{let o=this.liopServer.listTools(),s=await this.getRemoteTools(),a$1=L()?o.map(d=>({...d,description:ie(d.description??"")})):o;a.info(`[LIOP-Router] tools/list: ${o.length} local, ${s.length} remote tools found`);let u=[{name:"LiopMeshStatus",description:"LiopMeshStatus: Returns the current dynamic diagnostic status of the Zero-Trust Neural Mesh.",inputSchema:{type:"object",properties:{},additionalProperties:false}},...a$1,...s],p=I.getInstance(),m=JSON.stringify(u),h=JSON.stringify({tools:u});return p.record({type:"tools_list",method:"tools/list",estimatedInputTokens:p.countTokens(m),estimatedOutputTokens:p.countTokens(h)}),{jsonrpc:"2.0",id:i,result:{tools:u}}}case "tools/call":return this.transcodeMcpToLiop(i,n,t?.token);case "resources/list":{let o=this.liopServer.listResources(),s=await this.getRemoteResources(),a=[...o,...s],l=I.getInstance(),u=JSON.stringify(a);return l.record({type:"resource_list",method:"resources/list",estimatedInputTokens:0,estimatedOutputTokens:l.countTokens(u)}),{jsonrpc:"2.0",id:i,result:{resources:a}}}case "resources/read":{let o=n;if(!o?.uri)return {jsonrpc:"2.0",id:i,error:{code:-32602,message:"Missing resource uri"}};try{let s=Date.now(),a=await this.liopServer.readResource(o.uri),l=I.getInstance(),u=JSON.stringify(a);return l.record({type:"resource_read",method:"resources/read",toolName:o.uri,estimatedInputTokens:l.countTokens(o.uri),estimatedOutputTokens:l.countTokens(u),durationMs:Date.now()-s}),{jsonrpc:"2.0",id:i,result:a}}catch(s){let a$1=o.uri;for(let{manifest:l}of this.manifestCache.values()){let u=l.resources.find(p=>p.uri===a$1);if(u)return a.info(`[LIOP-Router] Resolved resource ${a$1} from cache (Peer: ${l.peerId})`),{jsonrpc:"2.0",id:i,result:{contents:[{uri:u.uri,mimeType:u.mimeType||"text/plain",text:u.text||u.description||"No content provided"}]}}}return {jsonrpc:"2.0",id:i,error:{code:-32e3,message:s instanceof Error?s.message:String(s)}}}}case "prompts/list":{let o=this.liopServer.listPrompts(),s=I.getInstance(),a=JSON.stringify(o);return s.record({type:"prompt_list",method:"prompts/list",estimatedInputTokens:0,estimatedOutputTokens:s.countTokens(a)}),{jsonrpc:"2.0",id:i,result:{prompts:o}}}case "prompts/get":{let o=n;if(!o?.name)return {jsonrpc:"2.0",id:i,error:{code:-32602,message:"Missing prompt name"}};try{let s=Date.now(),a=await this.liopServer.getPrompt({name:o.name,arguments:o.arguments||{}}),l=I.getInstance(),u=JSON.stringify({name:o.name,arguments:o.arguments}),p=JSON.stringify(a);return l.record({type:"prompt_get",method:"prompts/get",toolName:o.name,estimatedInputTokens:l.countTokens(u),estimatedOutputTokens:l.countTokens(p),durationMs:Date.now()-s}),{jsonrpc:"2.0",id:i,result:a}}catch(s){return {jsonrpc:"2.0",id:i,error:{code:-32e3,message:s instanceof Error?s.message:String(s)}}}}default:return {jsonrpc:"2.0",id:i,error:{code:-32601,message:`Method not found: ${r}`}}}}kickDiscoveryAfterInitialized(){return (async()=>{await new Promise(e=>setTimeout(e,250)),await Promise.race([this.refreshManifestCache(true),new Promise(e=>setTimeout(e,15e3))]).catch(()=>{});})()}async refreshManifestCache(e=false){if(this.meshNode){if(this.currentDiscovery)return this.currentDiscovery;if(!e&&this.manifestCache.size>0){let t=Date.now();if(Array.from(this.manifestCache.values()).every(({cachedAt:n})=>t-n<ve*1e3))return}return this.currentDiscovery=(async()=>{try{let t=Array.from(this.manifestCache.values()).reduce((m,{manifest:h})=>m+h.tools.length,0);if(this.manifestCache.size===0)for(let m=0;m<3;m++){if((this.meshNode.node?.getConnections().length||0)>0){a.info("[LIOP-Router] P2P Connection established. Starting discovery...");break}a.info(`[LIOP-Router] Waiting for P2P connections (attempt ${m+1}/10)...`),await new Promise(d=>setTimeout(d,1e3));}let r=[],n=this.manifestCache.size===0?5:1;for(let m=0;m<n;m++){for(let T=0;T<ae;T++){r=await this.meshNode?.discoverManifestProviders()||[];let y=this.meshNode?.getPeerId();if(r.filter(k=>k!==y).length>0)break;T<ae-1&&(a.info(`[LIOP-Router] DHT discovery attempt ${T+1}/${ae}...`),await new Promise(k=>setTimeout(k,1e3)));}let h=this.meshNode.node?.getConnections().map(T=>T.remotePeer.toString())||[];h.length>0&&(r=Array.from(new Set([...r,...h])));let d=this.meshNode?.getPeerId();if(r.filter(T=>T!==d).length>0)break;m<n-1&&(a.info(`[LIOP-Router] Initial discovery failed (0 providers). Retrying in 1s (${m+1}/${n})...`),await new Promise(T=>setTimeout(T,1e3)));}if(r.length===0){a.info("[LIOP-Router] No manifest providers found after all attempts.");return}e||a.info(`[LIOP-Router] Discovered ${r.length} candidate manifest providers`);let i=new Set((this.meshNode.node?.getConnections?.()||[]).map(m=>m.remotePeer.toString()));r=[...r].sort((m,h)=>{let d=i.has(m)?1:0;return (i.has(h)?1:0)-d});let o=0,s=0,a$1=!1,l=this.meshNode?.getPeerId(),u=r.filter(m=>{if(!this.meshNode||m===l||this.shouldSkipManifestQuery(m))return !1;let h=this.manifestCache.get(m);return h&&Date.now()-h.cachedAt<ve*1e3?(o++,!1):!0}),p=await Promise.allSettled(u.map(async m=>this.meshNode?(a.info(`[LIOP-Router] Querying manifest from: ${m}`),{peerId:m,manifest:await this.meshNode.queryManifest(m)}):null));for(let m of p)if(m.status==="fulfilled"&&m.value?.manifest){let{peerId:h,manifest:d}=m.value;this.manifestCache.set(h,{manifest:d,cachedAt:Date.now()}),this.recordManifestQuerySuccess(h),a$1=!0,o++,a.info(`[LIOP-Router] Manifest received from ${h} (${d.tools.length} tools)`);}else m.status==="fulfilled"&&m.value?(this.recordManifestQueryFailure(m.value.peerId),s++,a.info(`[LIOP-Router] Manifest query returned NULL for ${m.value.peerId}`)):m.status==="rejected"&&(s++,a.info("[LIOP-Router] Fatal error querying manifest:",m.reason instanceof Error?m.reason.message:String(m.reason)));this._discoveryStats={candidates:r.length,success:o,failures:s,lastDiscovery:Date.now()},a$1&&Array.from(this.manifestCache.values()).reduce((h,{manifest:d})=>h+d.tools.length,0)!==t&&this.onToolsChanged&&(process.stderr.write(`[LIOP-Router] Mesh topology updated! Emitting notifications/tools/list_changed.
|
|
10
|
+
`),this.onToolsChanged());}finally{this.currentDiscovery=null;}})(),this.currentDiscovery}}getCacheSize(){return this.manifestCache.size}async getRemoteTools(){let e=Number.parseInt(process.env.LIOP_EXPECTED_PROVIDERS??"1",10);if(this.manifestCache.size<e&&this.meshNode){let i=Number.parseInt(process.env.LIOP_INITIAL_DISCOVERY_TIMEOUT_MS??"8000",10),o=Number.isFinite(i)&&i>0?i:12e3,s=Date.now()+o,a$1=0,l=-1;for(;Date.now()<s&&!(this.manifestCache.size>=e||(await Promise.race([this.refreshManifestCache(true),new Promise(u=>setTimeout(u,3e3))]).catch(()=>{}),this.manifestCache.size>=e));){if(this.manifestCache.size===l){if(a$1++,a$1>=3&&this.manifestCache.size>0){a.info(`[LIOP-Router] Provider count stabilized at ${this.manifestCache.size}/${e}. Proceeding with available mesh.`);break}}else a$1=0,l=this.manifestCache.size;await new Promise(u=>setTimeout(u,1e3));}this.manifestCache.size<e&&(a.info(`[LIOP-Router] \u26A0\uFE0F Mesh partially available: ${this.manifestCache.size}/${e} providers. Some tools may be unavailable. Check Docker containers.`),this.refreshManifestCache(true).catch(()=>{}));}let t=[],r=new Set,n=new Set(this.liopServer.listTools().map(i=>i.name));for(let[i,{manifest:o}]of this.manifestCache.entries())for(let s of o.tools){if(s.name==="LiopMeshStatus")continue;let a=s.name;(r.has(s.name)||n.has(s.name))&&(a=`${s.name}_${i.slice(-4)}`),r.add(a);let l=o.serverInfo?.name||"Unknown Provider",u=s.description||`Remote tool from ${l}`,p={name:a,description:L()?ie(u):u,inputSchema:s.inputSchema||{type:"object",properties:{}}};typeof p.inputSchema=="object"&&!p.inputSchema.type&&(p.inputSchema.type="object"),typeof p.inputSchema=="object"&&!p.inputSchema.properties&&(p.inputSchema.properties={});let m="";o.taxonomy&&(m=`
|
|
11
|
+
[LIOP-DOMAIN: ${o.taxonomy.domain}]`);let h=p.inputSchema.properties||{},d="";!L()&&h.payload&&(d=`
|
|
12
|
+
[REQUIRES: LIOP-PROTO-V1 ENVELOPE]`),!L()&&p.description.includes("STRICT SCHEMA ADHERENCE")&&(p.description=p.description.replace("STRICT SCHEMA ADHERENCE:","[INDUSTRIAL-REQUISITE] STRICT SCHEMA ADHERENCE (MANDATORY):"));let g=L()?`
|
|
13
|
+
(Peer: ${i.slice(-8)})${m}`:`
|
|
14
|
+
(Origin: ${i.slice(-8)})${m}${d}`;p.description=`${p.description}${g}`,t.push(p);}return t}async getRemoteResources(){this.currentDiscovery||this.refreshManifestCache(true).catch(()=>{});let e=[],t=new Set(this.liopServer.listResources().map(r=>r.uri));for(let[r,{manifest:n}]of this.manifestCache.entries())for(let i of n.resources)if(!t.has(i.uri)){let o={...i},s=n.serverInfo?.name||"Unknown Provider",a="";n.taxonomy&&(a=`
|
|
15
|
+
|
|
16
|
+
[LIOP Zero-Trust Blueprint]
|
|
17
|
+
Domain: ${n.taxonomy.domain}
|
|
18
|
+
Clearance Tier: ${n.taxonomy.clearanceTier}`,n.taxonomy.executionTypes&&n.taxonomy.executionTypes.length>0&&(a+=`
|
|
19
|
+
Execution Types: ${n.taxonomy.executionTypes.join(", ")}`));let l=`
|
|
20
|
+
|
|
21
|
+
[LIOP Zero-Trust Origin]
|
|
22
|
+
Provider: ${s}
|
|
23
|
+
Network ID: ${r}${a}`;o.uri.startsWith("liop://schema/")?(o.name=`[SCHEMA] ${o.name}`,o.description=`[CRITICAL SCHEMA] ${o.description||"Data Dictionary for Zero-Shot Autonomy"}${l}`):o.description=o.description?`${o.description}${l}`:l.trim(),e.push(o),t.add(i.uri);}return e}resolveManifestTarget(e){for(let[r,{manifest:n}]of this.manifestCache.entries())if(n.tools.find(o=>o.name===e))return {peerId:r,originalToolName:e};let t=e.split("_");if(t.length>1){let r=t.pop(),n=t.join("_");for(let[i,{manifest:o}]of this.manifestCache.entries())if(i.endsWith(r||"")&&o.tools.find(a=>a.name===n))return {peerId:i,originalToolName:n}}return null}redactPeerId(e){return (process.env.LIOP_DIAGNOSTIC_LEVEL||"redacted")==="full"?e:`***${e.slice(-8)}`}async transcodeMcpToLiop(e,t,r){let n=t.name;if(n==="LiopMeshStatus"){this.refreshManifestCache(true).catch(()=>{});let o=this._discoveryStats||{candidates:0,success:0,failures:0},s=this.manifestCache.size,a=this.meshNode?"Active":"Offline",l=Array.from(this.manifestCache.values()).reduce((P,{manifest:E})=>P+E.tools.length,0),u=this.meshNode?this.meshNode.node?.getConnections().length:0,p=this.meshNode&&this.meshNode.config?.bootstrapNodes?this.meshNode.config.bootstrapNodes:[],m=p.length,d=(process.env.LIOP_DIAGNOSTIC_LEVEL||"redacted")!=="minimal",g=d?p.map(P=>{let E=P.split("/"),S=E[E.length-1];return ` \u2022 ${S?S.slice(-8):"Unknown"} (bootstrap)`}).join(`
|
|
24
|
+
`):"",T=this.meshNode?this.meshNode.getRoutingTableSize():0,y=this.meshNode?.getPeerId()||"Offline",R=y==="Offline"?y:this.redactPeerId(y),k=Array.from(this.manifestCache.entries()).flatMap(([P,{manifest:E}])=>E.tools.map(S=>` \u2022 ${S.name} (from origin: ${this.redactPeerId(P)})`)).join(`
|
|
25
|
+
`),j=[`LIOP Mesh Status: ${a==="Active"?"Active":"Offline"}`,`Local Agent Identity: ${R}`,`Network: ${u} Conns | ${T} Mesh Nodes | ${m} Bootstraps`,d&&m>0?`
|
|
26
|
+
Active Bootstraps:
|
|
27
|
+
${g}
|
|
28
|
+
`:"",`Discovery: ${o.candidates} Candidates | ${o.success} OK | ${o.failures} FAIL`,`Tooling: ${s} Providers | ${l} Total Remote Tools`,l>0?`
|
|
29
|
+
Discovered Remote Tools (Zero-Trust Origins):
|
|
30
|
+
${k}`:`
|
|
31
|
+
No remote tools discovered yet.`,I.getInstance().formatStatusBlock()].filter(P=>P!=="").join(`
|
|
32
|
+
`),M=I.getInstance();return M.record({type:"diagnostic",method:"tools/call",toolName:"LiopMeshStatus",estimatedInputTokens:0,estimatedOutputTokens:M.countTokens(j)}),{jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:j}]}}}let i=this.liopServer.listTools().some(o=>o.name===n);if(!i&&this.meshNode){let o=this.resolveManifestTarget(n);if(o||(await this.refreshManifestCache(),o=this.resolveManifestTarget(n)),o){a.info(`[LIOP-Router] Resolved ${n} via manifest cache (Peer: ${o.peerId}, Original: ${o.originalToolName})`);let a$1=this.manifestCache.get(o.peerId),l=r;if(a$1?.manifest.authRequired){let u=r||await this.getOrAcquireMeshAgentToken(o.peerId);if(!u){let p=a$1.manifest.serverInfo?.name?.toLowerCase()||"unknown",m=a$1.manifest.tokenSlug,h=o.peerId.slice(-8).toUpperCase(),d=m?`LIOP_TOKEN_${m}`:`LIOP_TOKEN_${p.toUpperCase().replace(/[^A-Z0-9_]/g,"_")}`;return {jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:`Authentication Required: The restricted node (${p}) requires an access token. Please define the ${d} or LIOP_TOKEN_${h} environment variable on your agent/client host.`}],isError:true}}}l=u;}return this.routeToRemoteProvider(e,o.originalToolName,o.peerId,t,l)}let s=[];for(let a=0;a<3&&(s=await this.meshNode.findProviders(n),!(s.length>0));a++)a<2&&await new Promise(l=>setTimeout(l,1e3));if(s.length>0)return this.routeToRemoteProvider(e,n,s[0],t,r)}if(i)try{let o=Date.now(),s=await this.liopServer.callTool({name:n,arguments:t.arguments||{}}),a=I.getInstance(),l=JSON.stringify(t.arguments||{}),u=JSON.stringify(s);return a.record({type:"tool_call",method:"tools/call",toolName:n,estimatedInputTokens:a.countTokens(l),estimatedOutputTokens:a.countTokens(u),durationMs:Date.now()-o}),{jsonrpc:"2.0",id:e,result:s}}catch(o){return {jsonrpc:"2.0",id:e,error:{code:-32e3,message:o instanceof Error?o.message:String(o)}}}return {jsonrpc:"2.0",id:e,error:{code:-32002,message:`No provider found for tool: ${n}. Ensure the provider node is active and connected to the mesh.`}}}async routeToRemoteProvider(e,t,r,n,i){if(!this.meshNode)return {jsonrpc:"2.0",id:e,error:{code:-32603,message:"Mesh Node inactive"}};let o=this.manifestCache.get(r),s=this.defaultRpcPort;if(o)s=o.manifest.grpcPort;else {let d=await this.meshNode.queryManifest(r);d&&(s=d.grpcPort,this.manifestCache.set(r,{manifest:d,cachedAt:Date.now()}),o=this.manifestCache.get(r));}if((process.env.LIOP_USE_PUBLISHED_GRPC_PORTS==="1"||process.env.LIOP_DOCKER_MAP==="true"||process.env.LIOP_DEV_MODE==="true"||process.env.NODE_ENV==="development"||process.env.NODE_ENV==="test")&&o){let d=o.manifest.serverInfo?.name?.toLowerCase()||"";d.includes("vault")?s=13011:d.includes("bank")?s=13021:d.includes("oracle")&&(s=13031);}let l=await this.meshNode.resolvePeer(r),u=null,p=await import('os'),m=Object.values(p.networkInterfaces()).flat().filter(d=>d?.family==="IPv4").map(d=>d?.address);for(let d of l){let g=d.split("/"),T=g.indexOf("ip4");if(T!==-1){let y=g[T+1];if(y==="127.0.0.1"||m.includes(y)){u=`127.0.0.1:${s}`;break}u||(u=`${y}:${s}`);}}u||(u=`127.0.0.1:${s}`),a.info(`[LIOP-Router] Dynamic route: ${t} -> ${u} (PeerID: ${r})`);let h=new a$3.LogicMesh(u,c());return this.performTranscoding(e,h,t,n,r,i)}meshAgentToken;async getOrAcquireMeshAgentToken(e){if(e){let s=this.manifestCache.get(e),a$1=s?.manifest.serverInfo?.name?.toLowerCase()||"",l,u=s?.manifest.tokenSlug;if(u){let p=`LIOP_TOKEN_${u}`;l=process.env[p]||process.env[`LIOP_OAUTH_TOKEN_${u}`],a.info(`[LIOP-Router] Step0 tokenSlug=${u} envKey=${p} found=${!!l} peer=${e.slice(-8)}`);}else a.info(`[LIOP-Router] Step0 tokenSlug=MISSING (manifest has no tokenSlug) peer=${e.slice(-8)} provider=${a$1}`);if(!l){let p=e.slice(-8).toUpperCase();l=process.env[`LIOP_TOKEN_${p}`]||process.env[`LIOP_OAUTH_TOKEN_${p}`];}if(!l&&a$1){let p=a$1.toUpperCase().replace(/[^A-Z0-9_]/g,"_");l=process.env[`LIOP_TOKEN_${p}`]||process.env[`LIOP_OAUTH_TOKEN_${p}`];}if(l)return a.info(`[LIOP-Router] Resolved node-specific token for peer ${e.slice(-8)} (${a$1||"unknown"})`),l}if(this.meshAgentToken)return this.meshAgentToken;let t=process.env.LIOP_OAUTH_TOKEN||process.env.LIOP_TOKEN;if(t)return this.meshAgentToken=t,this.meshAgentToken;let r=process.env.LIOP_NEXUS_URL;if(!r)return;let n=process.env.LIOP_OAUTH_CLIENT_ID||process.env.LIOP_CLIENT_ID||"liop-mesh-agent",i=process.env.LIOP_OAUTH_CLIENT_SECRET||process.env.LIOP_CLIENT_SECRET||"dev-secret-change-me",o=process.env.LIOP_OAUTH_AUDIENCE||process.env.LIOP_AUDIENCE||"urn:liop:mesh:api";try{let a$1=`${r.endsWith("/oidc")?r:`${r}/oidc`}/token`;a.info(`[LIOP-Router] Proactively acquiring M2M token from Nexus: ${a$1}`);let l=new URLSearchParams({grant_type:"client_credentials",scope:"liop:tools:call liop:tools:list liop:resources:read liop:schema:read liop:mesh:query",resource:o,client_id:n,client_secret:i}),u=await fetch(a$1,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:l.toString()});if(!u.ok){let m=await u.text();a.warn(`[LIOP-Router] M2M Token acquisition failed: ${u.status} ${m}`);return}let p=await u.json();if(p.access_token)return this.meshAgentToken=p.access_token,a.info("[LIOP-Router] M2M Token acquired successfully for router routing."),this.meshAgentToken}catch(s){a.warn(`[LIOP-Router] Failed to acquire M2M token: ${s instanceof Error?s.message:String(s)}`);}}async performTranscoding(e,t,r,n,i,o){let s=r,a=this.meshNode?await this.meshNode.sign(Buffer.from(s)):Buffer.from([]),l=Date.now(),u=o;if(u||(u=await this.getOrAcquireMeshAgentToken(i)),i){let p=this.manifestCache.get(i);if(p?.manifest.authRequired&&!u){let m=p.manifest.serverInfo?.name?.toLowerCase()||"unknown",h=p.manifest.tokenSlug,d=i.slice(-8).toUpperCase(),g=h?`LIOP_TOKEN_${h}`:`LIOP_TOKEN_${m.toUpperCase().replace(/[^A-Z0-9_]/g,"_")}`;return {jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:`Authentication Required: The restricted node (${m}) requires an access token. Please define the ${g} or LIOP_TOKEN_${d} environment variable on your agent/client host.`}],isError:true}}}}return new Promise(p=>{let m=new ce.Metadata;u&&m.add("authorization",`Bearer ${u}`),t.negotiateIntent({agent_did:`did:liop:${this.meshNode?.getPeerId()||"mcp-proxy"}`,capability_hash:s,proof_of_intent:a},m,async(h,d)=>{if(h||!d.accepted)return p({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:`PQC Handshake Failed: ${h?.message||"Rejected"}`}],isError:true}});let{ciphertext:g,sharedSecret:T}=await a$4.encapsulateAsymmetric(d.kyber_public_key),y=JSON.stringify(n.arguments||{}),R=`return { "__liop_proxy_tool": "${r}", "__liop_proxy_args": ${y} };`,k=K.randomBytes(12),j=this.encryptWithNonce(Buffer.from(R),T,k),M=new ce.Metadata;u&&M.add("authorization",`Bearer ${u}`);let P=t.executeLogic({session_token:d.session_token,wasm_binary:new Uint8Array(j),inputs:{},pqc_ciphertext:g,aes_nonce:k},M),E="",S=null;P.on("data",w=>{E+=w.semantic_evidence,S=w;}),P.on("end",async()=>{try{if(S&&!S.is_error){let Pe=Buffer.from(S.cryptographic_proof).toString("hex");if(!await this.verifier.verifyZkReceipt(Buffer.from(R),Pe,Buffer.from(S.zk_receipt),Buffer.from(T)))return p({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:"SECURITY ALERT: Remote response failed cryptographic integrity audit."}],isError:!0}})}let w=JSON.parse(E),q=I.getInstance();q.record({type:"tool_call",method:"tools/call",toolName:r,peerId:i,estimatedInputTokens:q.countTokens(y),estimatedOutputTokens:q.countTokens(E),durationMs:Date.now()-l}),p({jsonrpc:"2.0",id:e,result:w});}catch{p({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:E}]}});}}),P.on("error",w=>p({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:`LIOP gRPC Error: ${w.message}`}],isError:true}}));});})}encryptWithNonce(e,t,r){let n=K.createCipheriv("aes-256-gcm",t,r),i=Buffer.concat([n.update(e),n.final()]);return Buffer.concat([i,n.getAuthTag()])}};export{W as a,B as b,fe as c,he as d,H as e,I as f,Ie as g};//# sourceMappingURL=chunk-VGXNGTIC.js.map
|
|
33
|
+
//# sourceMappingURL=chunk-VGXNGTIC.js.map
|