UNPKG

@hashgraphonline/conversational-agent

Version:

Hashgraph Online conversational AI agent implementing HCS-10 communication, HCS-2 registries, and content inscription on Hedera

1 lines 75.1 kB
"use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("hedera-agent-kit"),t=require("@hashgraphonline/standards-agent-kit"),n=require("@hashgraphonline/standards-sdk"),s=require("zod"),r=require("@hashgraph/sdk"),o=require("bignumber.js"),i=require("@langchain/core/tools"),a=require("langchain/agents"),c=require("@langchain/core/prompts"),g=require("@langchain/openai"),l=require("@modelcontextprotocol/sdk/client/index.js"),h=require("@modelcontextprotocol/sdk/client/stdio.js"),u=require("tiktoken"),m=require("crypto"),d=require("@langchain/anthropic"),p=require("@langchain/core/messages");class f extends e.BasePlugin{constructor(){super(...arguments),this.id="hcs-10",this.name="HCS-10 Plugin",this.description="HCS-10 agent tools for decentralized agent registration, connections, and messaging on Hedera",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="hcs10",this.tools=[]}async initialize(e){await super.initialize(e);const s=e.config.hederaKit;if(s)try{this.stateManager=e.stateManager||e.config.stateManager||this.appConfig?.stateManager||new t.OpenConvaiState;const i=s.signer.getAccountId().toString();let a="",c="";try{const e=s.signer.getOperatorPrivateKey(),t="function"==typeof e?.toStringRaw?e.toStringRaw():"function"==typeof e?.toString?e.toString():String(e),r=new n.HCS10Client({network:s.network,operatorId:i,operatorPrivateKey:t,logLevel:"error"}),o=await r.retrieveProfile(i);o.success&&o.topicInfo&&(a=o.topicInfo.inboundTopic,c=o.topicInfo.outboundTopic)}catch(r){this.context.logger.warn("Could not retrieve profile topics:",r)}if(this.stateManager.setCurrentAgent({name:`Agent ${i}`,accountId:i,inboundTopicId:a,outboundTopicId:c,privateKey:(()=>{const e=s.signer.getOperatorPrivateKey();return"function"==typeof e?.toStringRaw?e.toStringRaw():"function"==typeof e?.toString?e.toString():String(e)})()}),this.context.logger.info(`Set current agent: ${i} with topics ${a}/${c}`),this.stateManager&&!this.stateManager.getConnectionsManager())try{const e=s.signer.getOperatorPrivateKey(),t="function"==typeof e?.toStringRaw?e.toStringRaw():"function"==typeof e?.toString?e.toString():String(e),r=new n.HCS10Client({network:s.network,operatorId:i,operatorPrivateKey:t,logLevel:"error"});this.stateManager.initializeConnectionsManager(r),this.context.logger.info("ConnectionsManager initialized in HCS10Plugin")}catch(o){this.context.logger.warn("Could not initialize ConnectionsManager:",o)}this.initializeTools(),this.context.logger.info("HCS-10 Plugin initialized successfully")}catch(i){this.context.logger.error("Failed to initialize HCS-10 plugin:",i)}else this.context.logger.warn("HederaKit not found in context. HCS-10 tools will not be available.")}initializeTools(){if(!this.stateManager)throw new Error("StateManager must be initialized before creating tools");const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const n=new t.HCS10Builder(e,this.stateManager);this.tools=[new t.RegisterAgentTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.FindRegistrationsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.RetrieveProfileTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.InitiateConnectionTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ListConnectionsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.SendMessageToConnectionTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.CheckMessagesTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ConnectionMonitorTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ManageConnectionRequestsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.AcceptConnectionRequestTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger}),new t.ListUnapprovedConnectionRequestsTool({hederaKit:e,hcs10Builder:n,logger:this.context.logger})]}getTools(){return this.tools}getStateManager(){return this.stateManager}async cleanup(){this.tools=[],delete this.stateManager,this.context?.logger&&this.context.logger.info("HCS-10 Plugin cleaned up")}}class y extends e.BasePlugin{constructor(){super(...arguments),this.id="hcs-2",this.name="HCS-2 Plugin",this.description="HCS-2 registry management tools for decentralized registries on Hedera",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="hcs2",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("HCS-2 Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize HCS-2 plugin:",t)}else this.context.logger.warn("HederaKit not found in context. HCS-2 tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const n=new t.HCS2Builder(e);this.tools=[new t.CreateRegistryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.RegisterEntryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.UpdateEntryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.DeleteEntryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.MigrateRegistryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger}),new t.QueryRegistryTool({hederaKit:e,hcs2Builder:n,logger:this.context.logger})]}getTools(){return this.tools}async cleanup(){this.tools=[],this.context?.logger&&this.context.logger.info("HCS-2 Plugin cleaned up")}}class w extends e.BasePlugin{constructor(){super(...arguments),this.id="inscribe",this.name="Inscribe Plugin",this.description="Content inscription tools for storing data on Hedera Consensus Service",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="inscribe",this.tools=[]}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("Inscribe Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize Inscribe plugin:",t)}else this.context.logger.warn("HederaKit not found in context. Inscription tools will not be available.")}initializeTools(){const e=this.context.config.hederaKit;if(!e)throw new Error("HederaKit not found in context config");const n=new t.InscriberBuilder(e);this.tools=[new t.InscribeFromUrlTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.InscribeFromFileTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.InscribeFromBufferTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.InscribeHashinalTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger}),new t.RetrieveInscriptionTool({hederaKit:e,inscriberBuilder:n,logger:this.context.logger})]}getTools(){return this.tools}async cleanup(){this.tools=[],this.context?.logger&&this.context.logger.info("Inscribe Plugin cleaned up")}}class T extends e.BaseServiceBuilder{constructor(e){super(e)}transferHbar(e,t=!0){this.clearNotes();const n=new r.TransferTransaction;if(!e.transfers||0===e.transfers.length)throw new Error("HbarTransferParams must include at least one transfer.");let s=new o(0),i=!1;if(t&&this.kit.userAccountId&&"provideBytes"===this.kit.operationalMode&&1===e.transfers.length){const t=e.transfers[0],s="string"==typeof t.amount||"number"==typeof t.amount?t.amount:t.amount.toString(),a=new o(s);if(a.isPositive()){const e="string"==typeof t.accountId?r.AccountId.fromString(t.accountId):t.accountId,s=a.toFixed(8,o.ROUND_DOWN),c=r.Hbar.fromString(s);this.logger.info(`[AccountBuilder.transferHbar] Configuring user-initiated scheduled transfer: ${c.toString()} from ${this.kit.userAccountId} to ${e.toString()}`),this.addNote(`Configured HBAR transfer from your account (${this.kit.userAccountId}) to ${e.toString()} for ${c.toString()}.`),n.addHbarTransfer(e,c),n.addHbarTransfer(r.AccountId.fromString(this.kit.userAccountId),c.negated()),i=!0}}if(!i){const t=[];for(const n of e.transfers){const e="string"==typeof n.accountId?r.AccountId.fromString(n.accountId):n.accountId,i="string"==typeof n.amount||"number"==typeof n.amount?n.amount:n.amount.toString(),a=new o(i),c=a.toFixed(8,o.ROUND_DOWN);this.logger.info(`Processing transfer: ${i} HBAR (rounded to ${c}) for account ${e.toString()}`);const g=r.Hbar.fromString(c);t.push({accountId:e,amount:a,hbar:g});const l=g.toTinybars();s=s.plus(l.toString())}if(!s.isZero()&&(this.logger.warn(`Transfer sum not zero: ${s.toString()} tinybars off. Adjusting last transfer.`),t.length>0)){const e=t[t.length-1],n=s.dividedBy(-1e8),i=e.amount.plus(n).toFixed(8,o.ROUND_DOWN);e.hbar=r.Hbar.fromString(i),this.logger.info(`Adjusted last transfer for ${e.accountId.toString()} to ${i} HBAR`)}for(const e of t)n.addHbarTransfer(e.accountId,e.hbar)}return void 0!==e.memo&&(null===e.memo?this.logger.warn("Received null for memo in transferHbar."):n.setTransactionMemo(e.memo)),this.setCurrentTransaction(n),this}}const S=s.z.object({accountId:s.z.string().describe('Account ID for the transfer (e.g., "0.0.xxxx").'),amount:s.z.union([s.z.number(),s.z.string()]).describe("HBAR amount in decimal format (e.g., 1 for 1 HBAR, 0.5 for 0.5 HBAR). Positive for credit, negative for debit. DO NOT multiply by 10^8 for tinybars - just use the HBAR amount directly.")}),C=s.z.object({transfers:s.z.array(S).min(1).describe('Array of transfers. For simple transfers from your operator account, just include the recipient with positive amount: [{accountId: "0.0.800", amount: 1}]. For complex multi-party transfers, include all parties with negative amounts for senders and positive for receivers.'),memo:s.z.string().optional().describe("Optional. Memo for the transaction.")});class M extends e.BaseHederaTransactionTool{constructor(){super(...arguments),this.name="hedera-account-transfer-hbar-v2",this.description='PRIMARY TOOL FOR HBAR TRANSFERS: Transfers HBAR between accounts. For simple transfers from the operator account, just specify the recipient with a positive amount (e.g., [{accountId: "0.0.800", amount: 1}] to send 1 HBAR to 0.0.800). The sender will be automatically added. For multi-party transfers (e.g., "A sends 5 HBAR to C and B sends 3 HBAR to C"), include ALL transfers with their amounts (negative for senders, positive for receivers).',this.specificInputSchema=C,this.namespace="account"}getServiceBuilder(){return new T(this.hederaKit)}async callBuilderMethod(e,t){await e.transferHbar(t)}}class v extends i.StructuredTool{constructor(e,t){super(),this.name="hedera-hts-airdrop-token",this.description="Airdrops fungible tokens to multiple recipients. Automatically converts human-readable amounts to smallest units based on token decimals.",this.schema=s.z.object({tokenId:s.z.string().describe('The ID of the fungible token to airdrop (e.g., "0.0.yyyy").'),recipients:s.z.array(s.z.object({accountId:s.z.string().describe('Recipient account ID (e.g., "0.0.xxxx").'),amount:s.z.union([s.z.number(),s.z.string()]).describe('Amount in human-readable format (e.g., "10" for 10 tokens).')})).min(1).describe("Array of recipient objects, each with accountId and amount."),memo:s.z.string().optional().describe("Optional. Memo for the transaction.")}),this.originalTool=e,this.agentKit=t,this.logger=new n.Logger({module:"AirdropToolWrapper"})}async _call(e){try{this.logger.info(`Processing airdrop request for token ${e.tokenId} with ${e.recipients.length} recipients`);const t=(await this.getTokenInfo(e.tokenId)).decimals||0;this.logger.info(`Token ${e.tokenId} has ${t} decimal places`);const n=e.recipients.map(e=>{const n="string"==typeof e.amount?parseFloat(e.amount):e.amount,s=this.convertToSmallestUnits(n,t);return this.logger.info(`Converting amount for ${e.accountId}: ${n} tokens → ${s} smallest units`),{...e,amount:s.toString()}}),s={...e,recipients:n};return this.logger.info("Calling original airdrop tool with converted amounts"),await this.originalTool._call(s)}catch(t){throw this.logger.error("Error in airdrop tool wrapper:",t),t}}convertToSmallestUnits(e,t){return Math.floor(e*Math.pow(10,t))}async getTokenInfo(e){return await this.queryTokenInfo(e)}async queryTokenInfo(e){try{this.logger.info("Querying token info using mirror node");const t=this.agentKit.mirrorNode;if(t){const n=await t.getTokenInfo(e);if(n&&void 0!==n.decimals){const t=parseInt(n.decimals.toString())||0;return this.logger.info(`Token ${e} found with ${t} decimals`),{...n,decimals:t}}}else{this.logger.info("MirrorNode not found in agentKit, attempting to access via fetch");const t="mainnet"===(this.agentKit.network||"testnet")?"https://mainnet.mirrornode.hedera.com":"https://testnet.mirrornode.hedera.com",n=await fetch(`${t}/api/v1/tokens/${e}`);if(n.ok){const t=await n.json(),s=parseInt(String(t.decimals||"0"));return this.logger.info(`Token ${e} found with ${s} decimals via API`),{...t,decimals:s}}}throw new Error("Token data not found or missing decimals field")}catch(t){return this.logger.warn(`Failed to query token info for ${e}:`,t),this.logger.info("Falling back to assumed 0 decimal places (smallest units)"),{decimals:0}}}}class x extends e.BasePlugin{constructor(){super(...arguments),this.id="hbar",this.name="HBAR Plugin",this.description="HBAR operations: transfer tool with robust decimal handling and compatibility with airdrop improvements",this.version="1.0.0",this.author="Hashgraph Online",this.namespace="account",this.tools=[],this.originalAirdropTool=null}async initialize(e){await super.initialize(e);if(e.config.hederaKit)try{this.initializeTools(),this.context.logger.info("HBAR Plugin initialized successfully")}catch(t){this.context.logger.error("Failed to initialize HBAR plugin:",t)}else this.context.logger.warn("HederaKit not found in context. HBAR tools will not be available.")}initializeTools(){const t=this.context.config.hederaKit;if(!t)throw new Error("HederaKit not found in context config");const n=new M({hederaKit:t,logger:this.context.logger});this.tools=[n];try{this.context.logger.info("Creating wrapper for passed original airdrop tool");const n=new e.HederaAirdropTokenTool({hederaKit:t,logger:this.context.logger}),s=new v(n,t);this.tools.push(s),this.context.logger.info("Added wrapped airdrop tool to HBAR Plugin")}catch(s){this.context.logger.error("Error creating airdrop tool wrapper:",s)}this.context.logger.info(`HBAR Plugin tools initialized with ${this.tools.length} tools`)}getTools(){return this.tools}async shutdown(){this.tools=[]}}class k extends a.AgentExecutor{constructor(e){super(e),this.logger=new n.Logger({module:"ContentAwareAgentExecutor"})}}class A{constructor(e){this.config=e,this.tools=[],this.initialized=!1,this.logger=new n.Logger({module:"BaseAgent",silent:e.debug?.silent||!1})}getCore(){return this.agentKit}filterTools(e){let t=[...e];const n=this.config.filtering;return n?(n.namespaceWhitelist?.length&&(t=t.filter(e=>{const t=e.namespace;return!t||n.namespaceWhitelist.includes(t)})),n.toolBlacklist?.length&&(t=t.filter(e=>!n.toolBlacklist.includes(e.name))),n.toolPredicate&&(t=t.filter(n.toolPredicate)),this.logger.debug(`Filtered tools: ${e.length} → ${t.length}`),t):t}buildSystemPrompt(){const e=[],t=this.config.signer.getAccountId().toString(),n=this.config.execution?.userAccountId;this.config.messaging?.systemPreamble&&e.push(this.config.messaging.systemPreamble),e.push(`You are a helpful Hedera assistant. Your primary operator account is ${t}. You have tools to interact with the Hedera Hashgraph. When using any tool, provide all necessary parameters as defined by that tool's schema and description.`),n&&e.push(`The user you are assisting has a personal Hedera account ID: ${n}. IMPORTANT: When the user says things like "I want to send HBAR" or "transfer my tokens", you MUST use ${n} as the sender/from account. For example, if user says "I want to send 2 HBAR to 0.0.800", you must set up a transfer where ${n} sends the HBAR, not your operator account.`);return"autonomous"===(this.config.execution?.operationalMode||"returnBytes")?e.push(`\nOPERATIONAL MODE: 'autonomous'. Your goal is to execute transactions directly using your tools. Your account ${t} will be the payer for these transactions. Even if the user's account (${n||"a specified account"}) is the actor in the transaction body (e.g., sender of HBAR), you (the agent with operator ${t}) are still executing and paying. For HBAR transfers, ensure the amounts in the 'transfers' array sum to zero (as per tool schema), balancing with your operator account if necessary.`):this.config.execution?.scheduleUserTransactionsInBytesMode&&n?e.push(`\nOPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. When a user asks for a transaction to be prepared (e.g., creating a token, topic, transferring assets for them to sign, etc), you MUST default to creating a Scheduled Transaction using the appropriate tool with the metaOption 'schedule: true'. The user (with account ID ${n}) will be the one to ultimately pay for and (if needed) sign the inner transaction. Your operator account (${t}) will pay for creating the schedule entity itself. You MUST return the ScheduleId and details of the scheduled operation in a structured JSON format with these fields: success, op, schedule_id, description, payer_account_id_scheduled_tx, and scheduled_transaction_details.`):e.push(`\nOPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes when possible. When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), you MUST call the appropriate tool. IMPORTANT: Only use metaOption 'returnBytes: true' for tools that explicitly support it (like HBAR transfers, token operations). Many tools (inscriptions, HCS-2, HCS-20, etc.) do NOT support returnBytes and will execute directly - this is expected behavior. For tools without returnBytes support, simply call them with their standard parameters. If you need raw bytes for the user to sign for their own account ${n||"if specified"}, ensure the tool constructs the transaction body accordingly when returnBytes IS supported.`),!1!==this.config.messaging?.conciseMode&&e.push("\nAlways be concise. If the tool provides a JSON string as its primary output (especially in returnBytes mode), make your accompanying text brief. If the tool does not provide JSON output or an error occurs, your narrative becomes primary; if notes were generated by the tool in such cases, append them to your textual response."),this.config.messaging?.systemPostamble&&e.push(this.config.messaging.systemPostamble),e.join("\n")}isReady(){return this.initialized}}class b{constructor(e,t){this.contentStorage=e,this.logger=t}analyzeResponse(e){const t=[];let n=0;this.extractContentFromResponse(e,t),n=t.reduce((e,t)=>e+t.sizeBytes,0);const s=t.reduce((e,t)=>Math.max(e,t.sizeBytes),0);return{shouldProcess:t.some(e=>this.contentStorage.shouldUseReference("string"==typeof e.content?e.content:JSON.stringify(e.content))),contents:t,totalSize:n,largestContentSize:s}}async processResponse(e,t,n){try{const s=this.analyzeResponse(e);if(!s.shouldProcess)return{content:e,wasProcessed:!1};return await this.createReferencedResponse(e,s,t,n)}catch(s){return this.logger.error("Error processing MCP response:",s),{content:e,wasProcessed:!1,errors:[s instanceof Error?s.message:"Unknown processing error"]}}}extractContentFromResponse(e,t){if(null!=e)if(Array.isArray(e))e.forEach(e=>this.extractContentFromResponse(e,t));else{if("object"==typeof e){const n=e;if("text"===n.type&&"string"==typeof n.text)return void t.push({content:n.text,type:"text",sizeBytes:globalThis.Buffer.byteLength(n.text,"utf8"),mimeType:this.detectMimeType(n.text)});if("image"===n.type&&"string"==typeof n.data)return void t.push({content:n.data,type:"image",sizeBytes:Math.ceil(.75*n.data.length),mimeType:n.mimeType||"image/jpeg"});if("resource"===n.type&&n.resource){const e=JSON.stringify(n.resource);return void t.push({content:e,type:"resource",sizeBytes:globalThis.Buffer.byteLength(e,"utf8"),mimeType:"application/json"})}return void Object.values(n).forEach(e=>this.extractContentFromResponse(e,t))}"string"==typeof e&&e.length>1e3&&t.push({content:e,type:"text",sizeBytes:globalThis.Buffer.byteLength(e,"utf8"),mimeType:this.detectMimeType(e)})}}async createReferencedResponse(e,t,n,s){const r=this.deepClone(e),o=[];let i=!1,a=0;for(const l of t.contents)if(this.contentStorage.shouldUseReference("string"==typeof l.content?l.content:JSON.stringify(l.content)))try{const e=globalThis.Buffer.from("string"==typeof l.content?l.content:JSON.stringify(l.content),"utf8"),t={contentType:this.mapMimeTypeToContentType(l.mimeType),source:"mcp_tool",mcpToolName:`${n}::${s}`,tags:["mcp_response",n,s]};void 0!==l.mimeType&&(t.mimeType=l.mimeType);const o=await this.contentStorage.storeContentIfLarge(e,t);o&&(this.replaceContentInResponse(r,l.content,this.createLightweightReference(o)),i=!0,a+=e.length)}catch(g){o.push(`Failed to create reference: ${g instanceof Error?g.message:"Unknown error"}`)}const c={content:r,wasProcessed:!0,referenceCreated:i,originalSize:a};return o.length>0&&(c.errors=o),c}createLightweightReference(e){return{type:"content_reference",referenceId:e.referenceId,preview:e.preview,size:e.metadata.sizeBytes,contentType:e.metadata.contentType,format:"ref://{id}",_isReference:!0}}replaceContentInResponse(e,t,n){if(null!=e)if(Array.isArray(e))for(let s=0;s<e.length;s++)e[s]===t?e[s]=n:this.replaceContentInResponse(e[s],t,n);else if("object"==typeof e){const s=e;if("text"===s.type&&s.text===t){for(const e of Object.keys(s))delete s[e];for(const e of Object.keys(n))s[e]=n[e];return}for(const e in s)s[e]===t?s[e]=n:this.replaceContentInResponse(s[e],t,n)}}detectMimeType(e){return e.trim().startsWith("{")||e.trim().startsWith("[")?"application/json":e.includes("<html>")||e.includes("<!DOCTYPE")?"text/html":e.includes("# ")||e.includes("## ")?"text/markdown":"text/plain"}mapMimeTypeToContentType(e){return e?e.startsWith("text/plain")?"text":"application/json"===e?"json":"text/html"===e?"html":"text/markdown"===e?"markdown":e.startsWith("text/")?"text":"binary":"text"}deepClone(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(e=>this.deepClone(e));const t={};for(const n in e)e.hasOwnProperty(n)&&(t[n]=this.deepClone(e[n]));return t}}class P{constructor(e,t){this.clients=new Map,this.tools=new Map,this.logger=e,t&&(this.contentProcessor=new b(t,e))}async connectServer(e){try{if(this.isServerConnected(e.name))return{serverName:e.name,connected:!1,error:`Server ${e.name} is already connected`,tools:[]};if(e.transport&&"stdio"!==e.transport)throw new Error(`Transport ${e.transport} not yet supported`);const t=new h.StdioClientTransport({command:e.command,args:e.args,...e.env&&{env:e.env}}),n=new l.Client({name:`conversational-agent-${e.name}`,version:"1.0.0"},{capabilities:{}});await n.connect(t),this.clients.set(e.name,n);const s=(await n.listTools()).tools.map(t=>({...t,serverName:e.name}));return this.tools.set(e.name,s),this.logger.info(`Connected to MCP server ${e.name} with ${s.length} tools`),{serverName:e.name,connected:!0,tools:s}}catch(t){return this.logger.error(`Failed to connect to MCP server ${e.name}:`,t),{serverName:e.name,connected:!1,error:t instanceof Error?t.message:"Unknown error",tools:[]}}}async executeTool(e,t,n){const s=this.clients.get(e);if(!s)throw new Error(`MCP server ${e} not connected`);this.logger.debug(`Executing MCP tool ${t} on server ${e}`,n);try{const r=await s.callTool({name:t,arguments:n});if(this.contentProcessor){const n=await this.contentProcessor.processResponse(r,e,t);return n.wasProcessed&&(this.logger.debug(`Processed MCP response from ${e}::${t}`,{referenceCreated:n.referenceCreated,originalSize:n.originalSize,errors:n.errors}),n.errors&&n.errors.length>0&&this.logger.warn(`Content processing warnings for ${e}::${t}:`,n.errors)),n.content}return r}catch(r){throw this.logger.error(`Error executing MCP tool ${t}:`,r),r}}async disconnectAll(){for(const[t,n]of this.clients)try{await n.close(),this.logger.info(`Disconnected from MCP server ${t}`)}catch(e){this.logger.error(`Error disconnecting MCP server ${t}:`,e)}this.clients.clear(),this.tools.clear()}getAllTools(){const e=[];for(const t of this.tools.values())e.push(...t);return e}getServerTools(e){return this.tools.get(e)||[]}isServerConnected(e){return this.clients.has(e)}getConnectedServers(){return Array.from(this.clients.keys())}enableContentProcessing(e){this.contentProcessor=new b(e,this.logger),this.logger.info("Content processing enabled for MCP responses")}disableContentProcessing(){delete this.contentProcessor,this.logger.info("Content processing disabled for MCP responses")}isContentProcessingEnabled(){return void 0!==this.contentProcessor}analyzeResponseContent(e){if(!this.contentProcessor)throw new Error("Content processing is not enabled");return this.contentProcessor.analyzeResponse(e)}}function I(e,t,s){const r=R(e.inputSchema),o=`${e.serverName}_${e.name}`.replace(/[^a-zA-Z0-9_]/g,"_");let a=e.description||`MCP tool ${e.name} from ${e.serverName}`;return s?.toolDescriptions?.[e.name]&&(a=`${a}\n\n${s.toolDescriptions[e.name]}`),s?.additionalContext&&(a=`${a}\n\nContext: ${s.additionalContext}`),new i.DynamicStructuredTool({name:o,description:a,schema:r,func:async s=>{try{const o=await t.executeTool(e.serverName,e.name,s);let i="";if("string"==typeof o)i=o;else if(o&&"object"==typeof o&&"content"in o){const e=o.content;if(Array.isArray(e)){i=e.filter(e=>"object"==typeof e&&null!==e&&"type"in e&&"text"===e.type&&"text"in e).map(e=>e.text).join("\n")}else i=JSON.stringify(e)}else i=JSON.stringify(o);const a=globalThis.Buffer.from(i,"utf8"),c=10240;if(a.length>c||n.shouldUseReference(a)){const t=n.ContentStoreService.getInstance();if(t)try{return`content-ref:${await t.storeContent(a,{contentType:"text",source:"mcp",mcpToolName:`${e.serverName}_${e.name}`,originalSize:a.length})}`}catch(r){}}return i}catch(o){const t=o instanceof Error?o.message:"Unknown error";return`Error executing MCP tool ${e.name}: ${t}`}}})}function R(e){if(!e||"object"!=typeof e)return s.z.object({});const t=e;if(t.type&&"object"!==t.type)return E(t);if(!t.properties||"object"!=typeof t.properties)return s.z.object({});const n={};for(const[s,r]of Object.entries(t.properties)){let e=E(r);Array.isArray(t.required)&&t.required.includes(s)||(e=e.optional()),n[s]=e}return s.z.object(n)}function E(e){if(!e||"object"!=typeof e||!("type"in e))return s.z.unknown();const t=e;let n;switch(t.type){case"string":n=s.z.string(),t.enum&&Array.isArray(t.enum)&&(n=s.z.enum(t.enum));break;case"number":n=s.z.number(),"minimum"in t&&"number"==typeof t.minimum&&(n=n.min(t.minimum)),"maximum"in t&&"number"==typeof t.maximum&&(n=n.max(t.maximum));break;case"integer":n=s.z.number().int(),"minimum"in t&&"number"==typeof t.minimum&&(n=n.min(t.minimum)),"maximum"in t&&"number"==typeof t.maximum&&(n=n.max(t.maximum));break;case"boolean":n=s.z.boolean();break;case"array":n=t.items?s.z.array(E(t.items)):s.z.array(s.z.unknown());break;case"object":n="properties"in t?R(t):s.z.object({}).passthrough();break;default:n=s.z.unknown()}return"description"in t&&"string"==typeof t.description&&(n=n.describe(t.description)),n}const z=class e{constructor(e="gpt-4o"){this.modelName=String(e);try{this.encoding=u.encoding_for_model(e)}catch{this.encoding=u.encoding_for_model("gpt-4o"),this.modelName="gpt-4o"}}countTokens(e){if(!e||""===e.trim())return 0;try{return this.encoding.encode(e).length}catch(t){return Math.ceil(1.3*e.split(/\s+/).length)}}countMessageTokens(t){return this.countTokens(String(t.content??""))+this.countTokens(this.getMessageRole(t))+e.MESSAGE_OVERHEAD+e.ROLE_OVERHEAD}countMessagesTokens(e){if(!e||0===e.length)return 0;let t=0;for(const n of e)t+=this.countMessageTokens(n);return t}estimateSystemPromptTokens(t){if(!t||""===t.trim())return 0;return this.countTokens(t)+this.countTokens("system")+e.MESSAGE_OVERHEAD+e.ROLE_OVERHEAD}estimateContextSize(e,t){return this.estimateSystemPromptTokens(e)+this.countMessagesTokens(t)+10}getMessageRole(e){switch(e._getType()){case"human":default:return"user";case"ai":return"assistant";case"system":return"system";case"function":return"function";case"tool":return"tool"}}getModelName(){return this.modelName}dispose(){try{this.encoding.free()}catch{}}};z.MESSAGE_OVERHEAD=3,z.ROLE_OVERHEAD=1;let B=z;const O=class e{constructor(t=e.DEFAULT_MAX_TOKENS,n=e.DEFAULT_RESERVE_TOKENS,s){if(this.messages=[],this.systemPrompt="",this.systemPromptTokens=0,n>=t)throw new Error("Reserve tokens must be less than max tokens");this.maxTokens=t,this.reserveTokens=n,this.tokenCounter=s||new B}addMessage(e){this.tokenCounter.countMessageTokens(e),this.messages.push(e);let t=[];return this.getCurrentTokenCount()>this.maxTokens-this.reserveTokens&&(this.messages.pop(),t=this.pruneToFit(),this.messages.push(e)),{added:!0,prunedMessages:t,currentTokenCount:this.getCurrentTokenCount(),remainingCapacity:this.getRemainingTokenCapacity()}}pruneToFit(){const t=[],n=this.maxTokens-this.reserveTokens;for(;this.getCurrentTokenCount()>n&&this.messages.length>0;){const n=Math.min(e.PRUNING_BATCH_SIZE,this.messages.length);for(let e=0;e<n;e++){const e=this.messages.shift();e&&t.push(e)}if(t.length>1e3)break}return t}getCurrentTokenCount(){const e=this.tokenCounter.countMessagesTokens(this.messages);return this.systemPromptTokens+e}getRemainingTokenCapacity(){return Math.max(0,this.maxTokens-this.getCurrentTokenCount())}canAddMessage(e){const t=this.tokenCounter.countMessageTokens(e),n=this.getCurrentTokenCount()+t>this.maxTokens-this.reserveTokens;return!(t>this.maxTokens)&&(!n||this.messages.length>0)}getMessages(){return[...this.messages]}clear(){this.messages=[]}setSystemPrompt(e){this.systemPrompt=e,this.systemPromptTokens=this.tokenCounter.estimateSystemPromptTokens(e)}getSystemPrompt(){return this.systemPrompt}getConfig(){return{maxTokens:this.maxTokens,reserveTokens:this.reserveTokens,currentTokens:this.getCurrentTokenCount(),messageCount:this.messages.length,systemPromptTokens:this.systemPromptTokens}}updateLimits(e,t){if(void 0!==t&&t>=e)throw new Error("Reserve tokens must be less than max tokens");this.maxTokens=e,void 0!==t&&(this.reserveTokens=t),this.getCurrentTokenCount()>this.maxTokens-this.reserveTokens&&this.pruneToFit()}getStats(){const e=this.getCurrentTokenCount(),t=this.maxTokens,n=e/t*100;return{totalMessages:this.messages.length,currentTokens:e,maxTokens:t,reserveTokens:this.reserveTokens,systemPromptTokens:this.systemPromptTokens,usagePercentage:Math.round(100*n)/100,remainingCapacity:this.getRemainingTokenCapacity(),canAcceptMore:this.getRemainingTokenCapacity()>this.reserveTokens}}dispose(){this.clear(),this.tokenCounter.dispose()}};O.DEFAULT_MAX_TOKENS=8e3,O.DEFAULT_RESERVE_TOKENS=1e3,O.PRUNING_BATCH_SIZE=2;let N=O;class ${static generateId(e){const t=m.createHash("sha256");return t.update(e),t.digest("hex")}static isValidReferenceId(e){return!(!e||"string"!=typeof e)&&(64===e.length&&/^[a-f0-9]+$/.test(e))}static extractReferenceId(e){if(!e||"string"!=typeof e)return null;const t=e.match(/^ref:\/\/([a-f0-9]{64})$/);return t?t[1]:this.isValidReferenceId(e)?e:null}static formatReference(e){return`ref://${e}`}static generateTestId(e){const t=globalThis.Buffer.from(`test-${e}-${Date.now()}`);return this.generateId(t)}}const H={sizeThresholdBytes:10240,maxAgeMs:36e5,maxReferences:100,maxTotalStorageBytes:104857600,enableAutoCleanup:!0,cleanupIntervalMs:3e5,enablePersistence:!1,storageBackend:"memory",cleanupPolicies:{recent:{maxAgeMs:18e5,priority:1},userContent:{maxAgeMs:72e5,priority:2},agentGenerated:{maxAgeMs:36e5,priority:3},default:{maxAgeMs:36e5,priority:4}}};class _ extends Error{constructor(e,t,n,s){super(e),this.type=t,this.referenceId=n,this.suggestedActions=s,this.name="ContentReferenceError"}}const D=class e{constructor(t=e.DEFAULT_MAX_STORAGE,n){this.messages=[],this.idCounter=0,this.contentStore=new Map,this.maxStorage=t,this.referenceConfig={...H,...n},this.referenceStats={activeReferences:0,totalStorageBytes:0,recentlyCleanedUp:0,totalResolutions:0,failedResolutions:0,averageContentSize:0,storageUtilization:0,performanceMetrics:{averageCreationTimeMs:0,averageResolutionTimeMs:0,averageCleanupTimeMs:0,creationTimes:[],resolutionTimes:[],cleanupTimes:[]}},this.referenceConfig.enableAutoCleanup&&this.startReferenceCleanupTimer()}storeMessages(e){if(0===e.length)return{stored:0,dropped:0};const t=new Date;let n=0;const s=e.map(e=>({message:e,storedAt:t,id:this.generateId()}));for(this.messages.push(...s);this.messages.length>this.maxStorage;)this.messages.shift(),n++;return{stored:s.length,dropped:n}}getRecentMessages(e){if(e<=0||0===this.messages.length)return[];const t=Math.max(0,this.messages.length-e);return this.messages.slice(t).map(e=>e.message)}searchMessages(e,t={}){if(!e||0===this.messages.length)return[];const{caseSensitive:n=!1,limit:s,useRegex:r=!1}=t;let o=[];if(r)try{const t=new RegExp(e,n?"g":"gi");o=this.messages.filter(e=>t.test(e.message.content)).map(e=>e.message)}catch(i){return[]}else{const t=n?e:e.toLowerCase();o=this.messages.filter(e=>{const s=e.message.content;return(n?s:s.toLowerCase()).includes(t)}).map(e=>e.message)}return s?o.slice(0,s):o}getMessagesFromTimeRange(e,t){return e>t||0===this.messages.length?[]:this.messages.filter(n=>n.storedAt>=e&&n.storedAt<=t).map(e=>e.message)}getStorageStats(){const e=this.messages.length,t=e>0?Math.round(e/this.maxStorage*100):0;let n,s;return e>0&&(n=this.messages[0].storedAt,s=this.messages[e-1].storedAt),{totalMessages:e,maxStorageLimit:this.maxStorage,usagePercentage:t,oldestMessageTime:n,newestMessageTime:s}}clear(){this.messages=[],this.idCounter=0}getTotalStoredMessages(){return this.messages.length}updateStorageLimit(e){if(e<=0)throw new Error("Storage limit must be greater than 0");for(this.maxStorage=e;this.messages.length>this.maxStorage;)this.messages.shift()}getMessagesByType(e,t){const n=this.messages.filter(t=>t.message._getType()===e).map(e=>e.message);return t?n.slice(0,t):n}getConfig(){return{maxStorage:this.maxStorage,currentUsage:this.messages.length,utilizationPercentage:this.messages.length/this.maxStorage*100}}generateId(){return`msg_${++this.idCounter}_${Date.now()}`}getRecentMessagesByTime(e){if(e<=0||0===this.messages.length)return[];const t=new Date(Date.now()-60*e*1e3);return this.messages.filter(e=>e.storedAt>=t).map(e=>e.message)}exportMessages(){return this.messages.map(e=>({content:e.message.content,type:e.message._getType(),storedAt:e.storedAt.toISOString(),id:e.id}))}shouldUseReference(e){return(globalThis.Buffer.isBuffer(e)?e.length:globalThis.Buffer.byteLength(e,"utf8"))>this.referenceConfig.sizeThresholdBytes}async storeContentIfLarge(e,t){const n=globalThis.Buffer.isBuffer(e)?e:globalThis.Buffer.from(e,"utf8");if(!this.shouldUseReference(n))return null;const s={contentType:t.contentType||this.detectContentType(n,t.mimeType),sizeBytes:n.length,source:t.source,tags:[]};return void 0!==t.mimeType&&(s.mimeType=t.mimeType),void 0!==t.mcpToolName&&(s.mcpToolName=t.mcpToolName),void 0!==t.fileName&&(s.fileName=t.fileName),void 0!==t.tags&&(s.tags=t.tags),void 0!==t.customMetadata&&(s.customMetadata=t.customMetadata),await this.storeContent(n,s)}async storeContent(e,t){const n=Date.now();try{const s=new Date,r=$.generateId(e),o={...t,createdAt:s,lastAccessedAt:s,accessCount:0},i={content:e,metadata:o,state:"active"},a=this.calculateExpirationTime(t.source);void 0!==a&&(i.expiresAt=a),this.contentStore.set(r,i),this.updateStatsAfterStore(e.length),await this.enforceReferenceStorageLimits();const c=this.createContentPreview(e,o.contentType),g={contentType:o.contentType,sizeBytes:o.sizeBytes,source:o.source};void 0!==o.fileName&&(g.fileName=o.fileName),void 0!==o.mimeType&&(g.mimeType=o.mimeType);const l={referenceId:r,state:"active",preview:c,metadata:g,createdAt:s,format:"ref://{id}"},h=Date.now()-n;return this.recordPerformanceMetric("creation",h),l}catch(s){const e=Date.now()-n;throw this.recordPerformanceMetric("creation",e),new _(`Failed to store content: ${s instanceof Error?s.message:"Unknown error"}`,"system_error",void 0,["Try again","Check storage limits","Contact administrator"])}}async resolveReference(e){const t=Date.now();try{if(!$.isValidReferenceId(e))return this.referenceStats.failedResolutions++,{success:!1,error:"Invalid reference ID format",errorType:"not_found",suggestedActions:["Check the reference ID format","Ensure the reference ID is complete"]};const n=this.contentStore.get(e);if(!n)return this.referenceStats.failedResolutions++,{success:!1,error:"Reference not found",errorType:"not_found",suggestedActions:["Verify the reference ID","Check if the content has expired","Request fresh content"]};if(n.expiresAt&&n.expiresAt<new Date)return n.state="expired",this.referenceStats.failedResolutions++,{success:!1,error:"Reference has expired",errorType:"expired",suggestedActions:["Request fresh content","Use alternative content source"]};if("active"!==n.state)return this.referenceStats.failedResolutions++,{success:!1,error:`Reference is ${n.state}`,errorType:"expired"===n.state?"expired":"corrupted",suggestedActions:["Request fresh content","Check reference validity"]};n.metadata.lastAccessedAt=new Date,n.metadata.accessCount++,this.referenceStats.totalResolutions++;const s=Date.now()-t;return this.recordPerformanceMetric("resolution",s),{success:!0,content:n.content,metadata:n.metadata}}catch(n){const e=Date.now()-t;return this.recordPerformanceMetric("resolution",e),this.referenceStats.failedResolutions++,{success:!1,error:`System error resolving reference: ${n instanceof Error?n.message:"Unknown error"}`,errorType:"system_error",suggestedActions:["Try again","Contact administrator"]}}}async hasReference(e){if(!$.isValidReferenceId(e))return!1;const t=this.contentStore.get(e);return!!t&&(t.expiresAt&&t.expiresAt<new Date?(t.state="expired",!1):"active"===t.state)}async cleanupReference(e){const t=this.contentStore.get(e);return!!t&&(this.referenceStats.totalStorageBytes-=t.content.length,this.referenceStats.activeReferences--,this.referenceStats.recentlyCleanedUp++,this.contentStore.delete(e),!0)}async getStats(){return this.updateReferenceStorageStats(),{...this.referenceStats,performanceMetrics:{averageCreationTimeMs:this.calculateAverage(this.referenceStats.performanceMetrics.creationTimes),averageResolutionTimeMs:this.calculateAverage(this.referenceStats.performanceMetrics.resolutionTimes),averageCleanupTimeMs:this.calculateAverage(this.referenceStats.performanceMetrics.cleanupTimes)}}}async updateConfig(e){this.referenceConfig={...this.referenceConfig,...e},this.cleanupTimer&&(clearInterval(this.cleanupTimer),delete this.cleanupTimer),this.referenceConfig.enableAutoCleanup&&this.startReferenceCleanupTimer()}async performCleanup(){const e=Date.now(),t=[];let n=0;try{const r=new Date,o=[];for(const[e,t]of this.contentStore.entries()){let n=!1;t.expiresAt&&t.expiresAt<r&&(n=!0,t.state="expired");const s=r.getTime()-t.metadata.createdAt.getTime();s>this.getCleanupPolicy(t.metadata.source).maxAgeMs&&(n=!0),"cleanup_pending"===t.state&&(n=!0),n&&o.push(e)}o.sort((e,t)=>{const n=this.contentStore.get(e),s=this.contentStore.get(t),r=this.getCleanupPolicy(n.metadata.source).priority;return this.getCleanupPolicy(s.metadata.source).priority-r});for(const e of o)try{await this.cleanupReference(e)&&n++}catch(s){t.push(`Failed to cleanup ${e}: ${s instanceof Error?s.message:"Unknown error"}`)}if(this.contentStore.size>this.referenceConfig.maxReferences){const e=Array.from(this.contentStore.entries()).sort(([,e],[,t])=>e.metadata.lastAccessedAt.getTime()-t.metadata.lastAccessedAt.getTime()),r=this.contentStore.size-this.referenceConfig.maxReferences;for(let o=0;o<r&&o<e.length;o++){const[r]=e[o];try{await this.cleanupReference(r)&&n++}catch(s){t.push(`Failed to cleanup excess reference ${r}: ${s instanceof Error?s.message:"Unknown error"}`)}}}const i=Date.now()-e;return this.recordPerformanceMetric("cleanup",i),{cleanedUp:n,errors:t}}catch(s){const r=Date.now()-e;this.recordPerformanceMetric("cleanup",r);const o=`Cleanup process failed: ${s instanceof Error?s.message:"Unknown error"}`;return t.push(o),{cleanedUp:n,errors:t}}}getReferenceConfig(){return{...this.referenceConfig}}async enforceReferenceStorageLimits(){this.contentStore.size>=this.referenceConfig.maxReferences&&await this.performCleanup(),this.referenceStats.totalStorageBytes>=this.referenceConfig.maxTotalStorageBytes&&await this.performCleanup()}calculateExpirationTime(e){const t=this.getCleanupPolicy(e);return new Date(Date.now()+t.maxAgeMs)}getCleanupPolicy(e){switch(e){case"mcp_tool":return this.referenceConfig.cleanupPolicies.recent;case"user_upload":return this.referenceConfig.cleanupPolicies.userContent;case"agent_generated":return this.referenceConfig.cleanupPolicies.agentGenerated;default:return this.referenceConfig.cleanupPolicies.default}}detectContentType(e,t){if(t)return"text/html"===t?"html":"text/markdown"===t?"markdown":"application/json"===t?"json":t.startsWith("text/")?"text":"binary";const n=e.toString("utf8",0,Math.min(e.length,1e3));return n.startsWith("{")||n.startsWith("[")?"json":n.includes("<html>")||n.includes("<!DOCTYPE")?"html":n.includes("#")&&n.includes("\n")?"markdown":"text"}createContentPreview(e,t){let n=e.toString("utf8",0,Math.min(e.length,400));if("html"===t)n=n.replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim();else if("json"===t)try{const e=JSON.parse(n);n=JSON.stringify(e,null,0)}catch{}return n=n.trim(),n.length>200&&(n=n.substring(0,200)+"..."),n||"[Binary content]"}updateStatsAfterStore(e){this.referenceStats.activeReferences++,this.referenceStats.totalStorageBytes+=e,this.updateReferenceStorageStats()}updateReferenceStorageStats(){let e;this.referenceStats.activeReferences>0&&(this.referenceStats.averageContentSize=this.referenceStats.totalStorageBytes/this.referenceStats.activeReferences),this.referenceStats.storageUtilization=this.referenceStats.totalStorageBytes/this.referenceConfig.maxTotalStorageBytes*100;let t=0;for(const[n,s]of this.contentStore.entries())s.metadata.accessCount>t&&(t=s.metadata.accessCount,e=n);void 0!==e?this.referenceStats.mostAccessedReferenceId=e:delete this.referenceStats.mostAccessedReferenceId}recordPerformanceMetric(e,t){const n=this.referenceStats.performanceMetrics;switch(e){case"creation":n.creationTimes.push(t),n.creationTimes.length>100&&n.creationTimes.shift();break;case"resolution":n.resolutionTimes.push(t),n.resolutionTimes.length>100&&n.resolutionTimes.shift();break;case"cleanup":n.cleanupTimes.push(t),n.cleanupTimes.length>100&&n.cleanupTimes.shift()}}calculateAverage(e){return 0===e.length?0:e.reduce((e,t)=>e+t,0)/e.length}startReferenceCleanupTimer(){this.cleanupTimer=setInterval(async()=>{try{await this.performCleanup()}catch(e){}},this.referenceConfig.cleanupIntervalMs)}async dispose(){this.cleanupTimer&&(clearInterval(this.cleanupTimer),delete this.cleanupTimer),this.contentStore.clear(),this.clear()}};D.DEFAULT_MAX_STORAGE=1e3;let L=D;const K='"isEntityAssociation":true',U=class e{constructor(t={}){this.config={...e.DEFAULT_CONFIG,...t},this.tokenCounter=new B(this.config.modelName),this._contentStorage=new L(this.config.storageLimit),this.memoryWindow=new N(this.config.maxTokens,this.config.reserveTokens,this.tokenCounter)}get contentStorage(){return this._contentStorage}addMessage(e){const t=this.memoryWindow.addMessage(e);t.prunedMessages.length>0&&this._contentStorage.storeMessages(t.prunedMessages)}getMessages(){return this.memoryWindow.getMessages()}clear(e=!1){this.memoryWindow.clear(),e&&this._contentStorage.clear()}setSystemPrompt(e){this.memoryWindow.setSystemPrompt(e)}getSystemPrompt(){return this.memoryWindow.getSystemPrompt()}searchHistory(e,t={}){return this._contentStorage.searchMessages(e,t)}getRecentHistory(e){return this._contentStorage.getRecentMessages(e)}canAddMessage(e){return this.memoryWindow.canAddMessage(e)}getMemoryStats(){const e=this.memoryWindow.getStats();return{totalActiveMessages:e.totalMessages,currentTokenCount:e.currentTokens,maxTokens:e.maxTokens,remainingCapacity:e.remainingCapacity,systemPromptTokens:e.systemPromptTokens,usagePercentage:e.usagePercentage}}getStorageStats(){return this._contentStorage.getStorageStats()}getOverallStats(){const e=this.getMemoryStats(),t=this.getStorageStats();return{activeMemory:e,storage:t,totalMessagesManaged:e.totalActiveMessages+t.totalMessages,activeMemoryUtilization:e.usagePercentage,storageUtilization:t.usagePercentage}}updateConfig(e){this.config={...this.config,...e},void 0===e.maxTokens&&void 0===e.reserveTokens||this.memoryWindow.updateLimits(this.config.maxTokens,this.config.reserveTokens),void 0!==e.storageLimit&&this._contentStorage.updateStorageLimit(this.config.storageLimit)}getConfig(){return{...this.config}}getHistoryFromTimeRange(e,t){return this._contentStorage.getMessagesFromTimeRange(e,t)}getHistoryByType(e,t){return this._contentStorage.getMessagesByType(e,t)}getRecentHistoryByTime(e){return this._contentStorage.getRecentMessagesByTime(e)}exportState(){return{config:this.config,activeMessages:this.memoryWindow.getMessages().map(e=>({content:e.content,type:e._getType()})),systemPrompt:this.memoryWindow.getSystemPrompt(),memoryStats:this.getMemoryStats(),storageStats:this.getStorageStats(),storedMessages:this._contentStorage.exportMessages()}}getContextSummary(e=!1){const t=this.getMessages(),n={activeMessageCount:t.length,systemPrompt:this.getSystemPrompt(),recentMessages:t.slice(-5),memoryUtilization:this.getMemoryStats().usagePercentage,hasStoredHistory:this.getStorageStats().totalMessages>0};return e?{...n,recentStoredMessages:this.getRecentHistory(10),storageStats:this.getStorageStats()}:n}performMaintenance(){}storeEntityAssociation(e,t,n,s){try{if(!e||"string"!=typeof e||0===e.trim().length)return;if(!t||"string"!=typeof t||0===t.trim().length)return;if(!n||"string"!=typeof n||0===n.trim().length)return;const r=e.trim(),o=t.trim().substring(0,100),i=n.trim().toLowerCase(),a={entityId:r,entityName:o,entityType:i,createdAt:new Date,isEntityAssociation:!0,...null!=s&&""!==s.trim()?{transactionId:s.trim()}:{}},c={_getType:()=>"system",content:JSON.stringify(a),id:`entity_${r}_${Date.now()}`,name:"entity_association",additional_kwargs:{entityId:r,entityName:o,entityType:i,isEntityAssociation:!0}};this._contentStorage.storeMessages([c])}catch(r){}}resolveEntityReference(e,t={}){try{if(!e||"string"!=typeof e)return[];const n=e.trim();if(0===n.length)return[];n.length;const{entityType:s,limit:r=10,fuzzyMatch:o=!0}=t,i=Math.max(1,Math.min(r||10,100)),a=/^0\.0\.\d+$/.test(n),c=this._contentStorage.searchMessages(n.substring(0,200),{caseSensitive:!1,limit:2*i}),g=[];for(const e of c)try{const t=e.content;if(t.includes(K)||t.includes("entityId")){const e=JSON.parse(t);if(e.entityId&&e.entityName&&e.entityType){if(s&&e.entityType!==s)continue;if(a&&e.entityId!==n)continue;g.push(e)}}}catch{continue}if(o&&0===g.length&&!a){const t=[e.toLowerCase(),"token","account",s||""].filter(Boolean);for(const n of t){if(n===e.toLowerCase())continue;const t=this._contentStorage.searchMessages(n,{caseSensitive:!1,limit:r});for(const e of t)try{const t=e.content;if(t.includes(K)){const e=JSON.parse(t);if(e.entityId&&e.entityName&&e.entityType){if(s&&e.entityType!==s)continue;g.push(e)}}}catch{continue}}}const l=g.filter((e,t,n)=>n.findIndex(t=>t.entityId===e.entityId)===t).sort((e,t)=>new Date(t.createdAt).getTime()-new Date(e.createdAt).getTime());return l.slice(0,i)}catch(n){return[]}}getEntityAssociations(e){try{const n=e?e.trim().toLowerCase():void 0;if(e&&(!n||0===n.length))return[];const s=n||"entityId",r=this._contentStorage.searchMessages(s,{caseSensitive:!1,limit:100}),o=[];for(const e of r)try{const t=e.content;if(t.includes(K)){const e=JSON.parse(t);if(e.entityId&&e.entityName&&e.entityType){if(n&&e.entityType!==n)continue;e.createdAt&&"string"==typeof e.createdAt&&(e.createdAt=new Date(e.createdAt)),o.push(e)}}}catch(t){continue}return o.filter((e,t,n)=>n.findIndex(t=>t.entityId===e.entityId)===t).sort((e,t)=>{const n=e=>e instanceof Date?e.getTime():new Date(e).getTime(),s=n(e.createdAt);return n(t.createdAt)-s})}catch(n){return[]}}dispose(){this.memoryWindow.dispose(),this._contentStorage.dispose(),this.tokenCounter.dispose()}};U.DEFAULT_CONFIG={maxTokens:8e3,reserveTokens:1e3,modelName:"gpt-4o",storageLimit:1e3};let F=U;class j extends A{constructor(){super(...arguments),this.systemMessage="",this.mcpConnectionStatus=new Map}async boot(){if(this.initialized)this.logger.warn("Agent already initialized");else try{this.agentKit=await this.createAgentKit(),await this.agentKit.initialize();const t=this.config.ai?.modelName||process.env.OPENAI_MODEL_NAME||"gpt-4o-mini";this.tokenTracker=new e.TokenUsageCallbackHandler(t);const n=this.agentKit.getAggregatedLangChainTools();this.tools=this.filterTools(n),this.config.mcp?.servers&&this.config.mcp.servers.length>0&&(!1!==this.config.mcp.autoConnect?await this.initializeMCP():(this.logger.info("MCP servers configured but autoConnect=false, skipping synchronous connection"),this.mcpManager=new P(this.logger))),this.smartMemory=new F({modelName:t,maxTokens:9e4,reserveTokens:1e4,storageLimit:1e3}),this.logger.info("SmartMemoryManager initialized:",{modelName:t,toolsCount:this.tools.length,maxTokens:9e4,reserveTokens:1e4}),this.systemMessage=this.buildSystemPrompt(),this.smartMemory.setSystemPrompt(this.systemMessage),await this.createExecutor(),this.initialized=!0,this.logger.info("LangChain Hedera agent initialized")}catch(t){throw this.logger.error("Failed to initialize agent:",t),t}}async chat(t,n){if(!this.initialized||!this.executor||!this