@hashgraphonline/conversational-agent 0.1.205 → 0.1.206
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/dist/cjs/base-agent.d.ts +6 -0
- package/dist/cjs/context/ReferenceContextManager.d.ts +84 -0
- package/dist/cjs/context/ReferenceResponseProcessor.d.ts +76 -0
- package/dist/cjs/conversational-agent.d.ts +34 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/langchain-agent.d.ts +1 -0
- package/dist/cjs/mcp/ContentProcessor.d.ts +37 -0
- package/dist/cjs/mcp/MCPClientManager.d.ts +19 -1
- package/dist/cjs/memory/ContentStorage.d.ts +205 -0
- package/dist/cjs/memory/MemoryWindow.d.ts +114 -0
- package/dist/cjs/memory/ReferenceIdGenerator.d.ts +45 -0
- package/dist/cjs/memory/SmartMemoryManager.d.ts +201 -0
- package/dist/cjs/memory/TokenCounter.d.ts +61 -0
- package/dist/cjs/memory/index.d.ts +7 -0
- package/dist/cjs/plugins/hbar-transfer/TransferHbarTool.d.ts +18 -0
- package/dist/cjs/services/ContentStoreManager.d.ts +54 -0
- package/dist/cjs/types/content-reference.d.ts +213 -0
- package/dist/cjs/types/index.d.ts +4 -0
- package/dist/esm/index12.js +15 -2
- package/dist/esm/index12.js.map +1 -1
- package/dist/esm/index14.js +119 -95
- package/dist/esm/index14.js.map +1 -1
- package/dist/esm/index15.js +159 -114
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index16.js +122 -81
- package/dist/esm/index16.js.map +1 -1
- package/dist/esm/index17.js +236 -0
- package/dist/esm/index17.js.map +1 -0
- package/dist/esm/index18.js +95 -0
- package/dist/esm/index18.js.map +1 -0
- package/dist/esm/index19.js +663 -0
- package/dist/esm/index19.js.map +1 -0
- package/dist/esm/index2.js +3 -1
- package/dist/esm/index2.js.map +1 -1
- package/dist/esm/index20.js +233 -0
- package/dist/esm/index20.js.map +1 -0
- package/dist/esm/index21.js +182 -0
- package/dist/esm/index21.js.map +1 -0
- package/dist/esm/index22.js +126 -0
- package/dist/esm/index22.js.map +1 -0
- package/dist/esm/index23.js +68 -0
- package/dist/esm/index23.js.map +1 -0
- package/dist/esm/index24.js +38 -0
- package/dist/esm/index24.js.map +1 -0
- package/dist/esm/index6.js +143 -84
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index7.js.map +1 -1
- package/dist/esm/index8.js +69 -5
- package/dist/esm/index8.js.map +1 -1
- package/dist/types/base-agent.d.ts +6 -0
- package/dist/types/context/ReferenceContextManager.d.ts +84 -0
- package/dist/types/context/ReferenceResponseProcessor.d.ts +76 -0
- package/dist/types/conversational-agent.d.ts +34 -0
- package/dist/types/langchain-agent.d.ts +1 -0
- package/dist/types/mcp/ContentProcessor.d.ts +37 -0
- package/dist/types/mcp/MCPClientManager.d.ts +19 -1
- package/dist/types/memory/ContentStorage.d.ts +205 -0
- package/dist/types/memory/MemoryWindow.d.ts +114 -0
- package/dist/types/memory/ReferenceIdGenerator.d.ts +45 -0
- package/dist/types/memory/SmartMemoryManager.d.ts +201 -0
- package/dist/types/memory/TokenCounter.d.ts +61 -0
- package/dist/types/memory/index.d.ts +7 -0
- package/dist/types/plugins/hbar-transfer/TransferHbarTool.d.ts +18 -0
- package/dist/types/services/ContentStoreManager.d.ts +54 -0
- package/dist/types/types/content-reference.d.ts +213 -0
- package/dist/types/types/index.d.ts +4 -0
- package/package.json +5 -3
- package/src/base-agent.ts +6 -0
- package/src/context/ReferenceContextManager.ts +345 -0
- package/src/context/ReferenceResponseProcessor.ts +296 -0
- package/src/conversational-agent.ts +166 -92
- package/src/langchain-agent.ts +89 -2
- package/src/mcp/ContentProcessor.ts +317 -0
- package/src/mcp/MCPClientManager.ts +61 -1
- package/src/mcp/adapters/langchain.ts +9 -4
- package/src/memory/ContentStorage.ts +954 -0
- package/src/memory/MemoryWindow.ts +247 -0
- package/src/memory/ReferenceIdGenerator.ts +84 -0
- package/src/memory/SmartMemoryManager.ts +323 -0
- package/src/memory/TokenCounter.ts +152 -0
- package/src/memory/index.ts +8 -0
- package/src/plugins/hbar-transfer/TransferHbarTool.ts +19 -1
- package/src/plugins/hcs-10/HCS10Plugin.ts +5 -4
- package/src/services/ContentStoreManager.ts +199 -0
- package/src/types/content-reference.ts +281 -0
- package/src/types/index.ts +6 -0
package/dist/esm/index7.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index7.js","sources":["../../src/base-agent.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport type { TransactionReceipt } from '@hashgraph/sdk';\nimport {\n HederaAgentKit,\n ServerSigner,\n TokenUsageCallbackHandler,\n TokenUsage,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport type { CostCalculation } from 'hedera-agent-kit';\nimport type { AIProvider, VercelAIProvider, BAMLProvider } from './providers';\nimport { Logger } from '@hashgraphonline/standards-sdk';\nimport type { MCPServerConfig } from './mcp/types';\n\nexport interface ToolFilterConfig {\n namespaceWhitelist?: string[];\n toolBlacklist?: string[];\n toolPredicate?: (tool: StructuredTool) => boolean;\n}\n\nexport type ExecutionMode = 'direct' | 'bytes';\nexport type OperationalMode = 'autonomous' | 'returnBytes';\n\nexport interface HederaAgentConfiguration {\n signer: ServerSigner;\n execution?: {\n mode?: ExecutionMode;\n operationalMode?: OperationalMode;\n userAccountId?: string;\n scheduleUserTransactions?: boolean;\n scheduleUserTransactionsInBytesMode?: boolean;\n };\n ai?: {\n provider?: AIProvider;\n llm?: unknown;\n apiKey?: string;\n modelName?: string;\n temperature?: number;\n };\n filtering?: ToolFilterConfig;\n messaging?: {\n systemPreamble?: string;\n systemPostamble?: string;\n conciseMode?: boolean;\n };\n extensions?: {\n plugins?: BasePlugin[];\n mirrorConfig?: Record<string, unknown>;\n modelCapability?: string;\n };\n mcp?: {\n servers?: MCPServerConfig[];\n autoConnect?: boolean;\n };\n debug?: {\n verbose?: boolean;\n silent?: boolean;\n };\n}\n\nexport interface ConversationContext {\n messages: BaseMessage[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface ChatResponse {\n output: string;\n message?: string;\n transactionBytes?: string;\n receipt?: TransactionReceipt | object;\n scheduleId?: string;\n transactionId?: string;\n notes?: string[];\n error?: string;\n intermediateSteps?: unknown;\n rawToolOutput?: unknown;\n tokenUsage?: TokenUsage;\n cost?: CostCalculation;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface UsageStats extends TokenUsage {\n cost: CostCalculation;\n}\n\nexport abstract class BaseAgent {\n protected logger: Logger;\n protected agentKit: HederaAgentKit | undefined;\n protected tools: StructuredTool[] = [];\n protected initialized = false;\n protected tokenTracker: TokenUsageCallbackHandler | undefined;\n\n constructor(protected config: HederaAgentConfiguration) {\n this.logger = new Logger({\n module: 'BaseAgent',\n silent: config.debug?.silent || false,\n });\n }\n\n abstract boot(): Promise<void>;\n abstract chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse>;\n abstract shutdown(): Promise<void>;\n abstract switchMode(mode: OperationalMode): void;\n abstract getUsageStats(): UsageStats;\n abstract getUsageLog(): UsageStats[];\n abstract clearUsageStats(): void;\n\n getCore(): HederaAgentKit | undefined {\n return this.agentKit;\n }\n\n protected filterTools(\n tools: StructuredTool[]\n ): StructuredTool[] {\n let filtered = [...tools];\n const filter = this.config.filtering;\n if (!filter) return filtered;\n\n if (filter.namespaceWhitelist?.length) {\n filtered = filtered.filter((tool) => {\n const namespace = (tool as StructuredTool & { namespace?: string })\n .namespace;\n return !namespace || filter.namespaceWhitelist!.includes(namespace);\n });\n }\n\n if (filter.toolBlacklist?.length) {\n filtered = filtered.filter(\n (tool) => !filter.toolBlacklist!.includes(tool.name)\n );\n }\n\n if (filter.toolPredicate) {\n filtered = filtered.filter(filter.toolPredicate);\n }\n\n this.logger.debug(`Filtered tools: ${tools.length} → ${filtered.length}`);\n return filtered;\n }\n\n protected buildSystemPrompt(): string {\n const parts: string[] = [];\n const operatorId = this.config.signer.getAccountId().toString();\n const userAccId = this.config.execution?.userAccountId;\n\n if (this.config.messaging?.systemPreamble) {\n parts.push(this.config.messaging.systemPreamble);\n }\n\n parts.push(\n `You are a helpful Hedera assistant. Your primary operator account is ${operatorId}. ` +\n `You have tools to interact with the Hedera network. ` +\n `When using any tool, provide all necessary parameters as defined by that tool's schema and description.`\n );\n\n if (userAccId) {\n parts.push(\n `The user you are assisting has a personal Hedera account ID: ${userAccId}. ` +\n `IMPORTANT: When the user says things like \"I want to send HBAR\" or \"transfer my tokens\", you MUST use ${userAccId} as the sender/from account. ` +\n `For example, if user says \"I want to send 2 HBAR to 0.0.800\", you must set up a transfer where ${userAccId} sends the HBAR, not your operator account.`\n );\n }\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n if (operationalMode === 'autonomous') {\n parts.push(\n `\\nOPERATIONAL MODE: 'autonomous'. Your goal is to execute transactions directly using your tools. ` +\n `Your account ${operatorId} will be the payer for these transactions. ` +\n `Even if the user's account (${\n userAccId || 'a specified account'\n }) is the actor in the transaction body (e.g., sender of HBAR), ` +\n `you (the agent with operator ${operatorId}) 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.`\n );\n } else {\n if (\n this.config.execution?.scheduleUserTransactionsInBytesMode &&\n userAccId\n ) {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. ` +\n `When a user asks for a transaction to be prepared (e.g., creating a token, topic, transferring assets for them to sign, etc), ` +\n `you MUST default to creating a Scheduled Transaction using the appropriate tool with the metaOption 'schedule: true'. ` +\n `The user (with account ID ${userAccId}) will be the one to ultimately pay for and (if needed) sign the inner transaction. ` +\n `Your operator account (${operatorId}) will pay for creating the schedule entity itself. ` +\n `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.`\n );\n } else {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes directly. ` +\n `When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), ` +\n `you MUST call the appropriate tool. If you want raw bytes for the user to sign for their own account ${\n userAccId || 'if specified'\n }, ensure the tool constructs the transaction body accordingly and use metaOption 'returnBytes: true' if available, or ensure the builder is configured for the user.`\n );\n }\n }\n\n if (this.config.messaging?.conciseMode !== false) {\n parts.push(\n '\\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.'\n );\n }\n\n if (this.config.messaging?.systemPostamble) {\n parts.push(this.config.messaging.systemPostamble);\n }\n\n return parts.join('\\n');\n }\n\n isReady(): boolean {\n return this.initialized;\n }\n}\n\nexport type { AIProvider, VercelAIProvider, BAMLProvider };\n"],"names":[],"mappings":";AAuFO,MAAe,UAAU;AAAA,EAO9B,YAAsB,QAAkC;AAAlC,SAAA,SAAA;AAJtB,SAAU,QAA0B,CAAA;AACpC,SAAU,cAAc;AAItB,SAAK,SAAS,IAAI,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,QAAQ,OAAO,OAAO,UAAU;AAAA,IAAA,CACjC;AAAA,EACH;AAAA,EAaA,UAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,YACR,OACkB;AAClB,QAAI,WAAW,CAAC,GAAG,KAAK;AACxB,UAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI,OAAO,oBAAoB,QAAQ;AACrC,iBAAW,SAAS,OAAO,CAAC,SAAS;AACnC,cAAM,YAAa,KAChB;AACH,eAAO,CAAC,aAAa,OAAO,mBAAoB,SAAS,SAAS;AAAA,MACpE,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,eAAe,QAAQ;AAChC,iBAAW,SAAS;AAAA,QAClB,CAAC,SAAS,CAAC,OAAO,cAAe,SAAS,KAAK,IAAI;AAAA,MAAA;AAAA,IAEvD;AAEA,QAAI,OAAO,eAAe;AACxB,iBAAW,SAAS,OAAO,OAAO,aAAa;AAAA,IACjD;AAEA,SAAK,OAAO,MAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,MAAM,EAAE;AACxE,WAAO;AAAA,EACT;AAAA,EAEU,oBAA4B;AACpC,UAAM,QAAkB,CAAA;AACxB,UAAM,aAAa,KAAK,OAAO,OAAO,aAAA,EAAe,SAAA;AACrD,UAAM,YAAY,KAAK,OAAO,WAAW;AAEzC,QAAI,KAAK,OAAO,WAAW,gBAAgB;AACzC,YAAM,KAAK,KAAK,OAAO,UAAU,cAAc;AAAA,IACjD;AAEA,UAAM;AAAA,MACJ,wEAAwE,UAAU;AAAA,IAAA;AAKpF,QAAI,WAAW;AACb,YAAM;AAAA,QACJ,gEAAgE,SAAS,2GACkC,SAAS,+HAChB,SAAS;AAAA,MAAA;AAAA,IAEjH;AAEA,UAAM,kBACJ,KAAK,OAAO,WAAW,mBAAmB;AAC5C,QAAI,oBAAoB,cAAc;AACpC,YAAM;AAAA,QACJ;AAAA,+GACkB,UAAU,0EAExB,aAAa,qBACf,+FACgC,UAAU;AAAA,MAAA;AAAA,IAEhD,OAAO;AACL,UACE,KAAK,OAAO,WAAW,uCACvB,WACA;AACA,cAAM;AAAA,UACJ;AAAA,8VAG+B,SAAS,8GACZ,UAAU;AAAA,QAAA;AAAA,MAG1C,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,+TAGI,aAAa,cACf;AAAA,QAAA;AAAA,MAEN;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,WAAW,gBAAgB,OAAO;AAChD,YAAM;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,KAAK,OAAO,WAAW,iBAAiB;AAC1C,YAAM,KAAK,KAAK,OAAO,UAAU,eAAe;AAAA,IAClD;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AACF;"}
|
|
1
|
+
{"version":3,"file":"index7.js","sources":["../../src/base-agent.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport type { TransactionReceipt } from '@hashgraph/sdk';\nimport {\n HederaAgentKit,\n ServerSigner,\n TokenUsageCallbackHandler,\n TokenUsage,\n BasePlugin,\n} from 'hedera-agent-kit';\nimport type { CostCalculation } from 'hedera-agent-kit';\nimport type { AIProvider, VercelAIProvider, BAMLProvider } from './providers';\nimport { Logger } from '@hashgraphonline/standards-sdk';\nimport type { MCPServerConfig } from './mcp/types';\n\nexport interface ToolFilterConfig {\n namespaceWhitelist?: string[];\n toolBlacklist?: string[];\n toolPredicate?: (tool: StructuredTool) => boolean;\n}\n\nexport type ExecutionMode = 'direct' | 'bytes';\nexport type OperationalMode = 'autonomous' | 'returnBytes';\n\nexport interface HederaAgentConfiguration {\n signer: ServerSigner;\n execution?: {\n mode?: ExecutionMode;\n operationalMode?: OperationalMode;\n userAccountId?: string;\n scheduleUserTransactions?: boolean;\n scheduleUserTransactionsInBytesMode?: boolean;\n };\n ai?: {\n provider?: AIProvider;\n llm?: unknown;\n apiKey?: string;\n modelName?: string;\n temperature?: number;\n };\n filtering?: ToolFilterConfig;\n messaging?: {\n systemPreamble?: string;\n systemPostamble?: string;\n conciseMode?: boolean;\n };\n extensions?: {\n plugins?: BasePlugin[];\n mirrorConfig?: Record<string, unknown>;\n modelCapability?: string;\n };\n mcp?: {\n servers?: MCPServerConfig[];\n autoConnect?: boolean;\n };\n debug?: {\n verbose?: boolean;\n silent?: boolean;\n };\n}\n\nexport interface ConversationContext {\n messages: BaseMessage[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface ChatResponse {\n output: string;\n message?: string;\n transactionBytes?: string;\n receipt?: TransactionReceipt | object;\n scheduleId?: string;\n transactionId?: string;\n notes?: string[];\n error?: string;\n intermediateSteps?: unknown;\n rawToolOutput?: unknown;\n tokenUsage?: TokenUsage;\n cost?: CostCalculation;\n metadata?: Record<string, unknown>;\n tool_calls?: Array<{\n id: string;\n name: string;\n args: Record<string, unknown>;\n output?: string;\n }>;\n [key: string]: unknown;\n}\n\nexport interface UsageStats extends TokenUsage {\n cost: CostCalculation;\n}\n\nexport abstract class BaseAgent {\n protected logger: Logger;\n protected agentKit: HederaAgentKit | undefined;\n protected tools: StructuredTool[] = [];\n protected initialized = false;\n protected tokenTracker: TokenUsageCallbackHandler | undefined;\n\n constructor(protected config: HederaAgentConfiguration) {\n this.logger = new Logger({\n module: 'BaseAgent',\n silent: config.debug?.silent || false,\n });\n }\n\n abstract boot(): Promise<void>;\n abstract chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse>;\n abstract shutdown(): Promise<void>;\n abstract switchMode(mode: OperationalMode): void;\n abstract getUsageStats(): UsageStats;\n abstract getUsageLog(): UsageStats[];\n abstract clearUsageStats(): void;\n\n getCore(): HederaAgentKit | undefined {\n return this.agentKit;\n }\n\n protected filterTools(\n tools: StructuredTool[]\n ): StructuredTool[] {\n let filtered = [...tools];\n const filter = this.config.filtering;\n if (!filter) return filtered;\n\n if (filter.namespaceWhitelist?.length) {\n filtered = filtered.filter((tool) => {\n const namespace = (tool as StructuredTool & { namespace?: string })\n .namespace;\n return !namespace || filter.namespaceWhitelist!.includes(namespace);\n });\n }\n\n if (filter.toolBlacklist?.length) {\n filtered = filtered.filter(\n (tool) => !filter.toolBlacklist!.includes(tool.name)\n );\n }\n\n if (filter.toolPredicate) {\n filtered = filtered.filter(filter.toolPredicate);\n }\n\n this.logger.debug(`Filtered tools: ${tools.length} → ${filtered.length}`);\n return filtered;\n }\n\n protected buildSystemPrompt(): string {\n const parts: string[] = [];\n const operatorId = this.config.signer.getAccountId().toString();\n const userAccId = this.config.execution?.userAccountId;\n\n if (this.config.messaging?.systemPreamble) {\n parts.push(this.config.messaging.systemPreamble);\n }\n\n parts.push(\n `You are a helpful Hedera assistant. Your primary operator account is ${operatorId}. ` +\n `You have tools to interact with the Hedera network. ` +\n `When using any tool, provide all necessary parameters as defined by that tool's schema and description.`\n );\n\n if (userAccId) {\n parts.push(\n `The user you are assisting has a personal Hedera account ID: ${userAccId}. ` +\n `IMPORTANT: When the user says things like \"I want to send HBAR\" or \"transfer my tokens\", you MUST use ${userAccId} as the sender/from account. ` +\n `For example, if user says \"I want to send 2 HBAR to 0.0.800\", you must set up a transfer where ${userAccId} sends the HBAR, not your operator account.`\n );\n }\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n if (operationalMode === 'autonomous') {\n parts.push(\n `\\nOPERATIONAL MODE: 'autonomous'. Your goal is to execute transactions directly using your tools. ` +\n `Your account ${operatorId} will be the payer for these transactions. ` +\n `Even if the user's account (${\n userAccId || 'a specified account'\n }) is the actor in the transaction body (e.g., sender of HBAR), ` +\n `you (the agent with operator ${operatorId}) 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.`\n );\n } else {\n if (\n this.config.execution?.scheduleUserTransactionsInBytesMode &&\n userAccId\n ) {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes' with scheduled transactions for user actions. ` +\n `When a user asks for a transaction to be prepared (e.g., creating a token, topic, transferring assets for them to sign, etc), ` +\n `you MUST default to creating a Scheduled Transaction using the appropriate tool with the metaOption 'schedule: true'. ` +\n `The user (with account ID ${userAccId}) will be the one to ultimately pay for and (if needed) sign the inner transaction. ` +\n `Your operator account (${operatorId}) will pay for creating the schedule entity itself. ` +\n `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.`\n );\n } else {\n parts.push(\n `\\nOPERATIONAL MODE: 'returnBytes'. Your goal is to provide transaction bytes directly. ` +\n `When a user asks for a transaction to be prepared (e.g., for them to sign, or for scheduling without the default scheduling flow), ` +\n `you MUST call the appropriate tool. If you want raw bytes for the user to sign for their own account ${\n userAccId || 'if specified'\n }, ensure the tool constructs the transaction body accordingly and use metaOption 'returnBytes: true' if available, or ensure the builder is configured for the user.`\n );\n }\n }\n\n if (this.config.messaging?.conciseMode !== false) {\n parts.push(\n '\\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.'\n );\n }\n\n if (this.config.messaging?.systemPostamble) {\n parts.push(this.config.messaging.systemPostamble);\n }\n\n return parts.join('\\n');\n }\n\n isReady(): boolean {\n return this.initialized;\n }\n}\n\nexport type { AIProvider, VercelAIProvider, BAMLProvider };\n"],"names":[],"mappings":";AA6FO,MAAe,UAAU;AAAA,EAO9B,YAAsB,QAAkC;AAAlC,SAAA,SAAA;AAJtB,SAAU,QAA0B,CAAA;AACpC,SAAU,cAAc;AAItB,SAAK,SAAS,IAAI,OAAO;AAAA,MACvB,QAAQ;AAAA,MACR,QAAQ,OAAO,OAAO,UAAU;AAAA,IAAA,CACjC;AAAA,EACH;AAAA,EAaA,UAAsC;AACpC,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,YACR,OACkB;AAClB,QAAI,WAAW,CAAC,GAAG,KAAK;AACxB,UAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI,OAAO,oBAAoB,QAAQ;AACrC,iBAAW,SAAS,OAAO,CAAC,SAAS;AACnC,cAAM,YAAa,KAChB;AACH,eAAO,CAAC,aAAa,OAAO,mBAAoB,SAAS,SAAS;AAAA,MACpE,CAAC;AAAA,IACH;AAEA,QAAI,OAAO,eAAe,QAAQ;AAChC,iBAAW,SAAS;AAAA,QAClB,CAAC,SAAS,CAAC,OAAO,cAAe,SAAS,KAAK,IAAI;AAAA,MAAA;AAAA,IAEvD;AAEA,QAAI,OAAO,eAAe;AACxB,iBAAW,SAAS,OAAO,OAAO,aAAa;AAAA,IACjD;AAEA,SAAK,OAAO,MAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,MAAM,EAAE;AACxE,WAAO;AAAA,EACT;AAAA,EAEU,oBAA4B;AACpC,UAAM,QAAkB,CAAA;AACxB,UAAM,aAAa,KAAK,OAAO,OAAO,aAAA,EAAe,SAAA;AACrD,UAAM,YAAY,KAAK,OAAO,WAAW;AAEzC,QAAI,KAAK,OAAO,WAAW,gBAAgB;AACzC,YAAM,KAAK,KAAK,OAAO,UAAU,cAAc;AAAA,IACjD;AAEA,UAAM;AAAA,MACJ,wEAAwE,UAAU;AAAA,IAAA;AAKpF,QAAI,WAAW;AACb,YAAM;AAAA,QACJ,gEAAgE,SAAS,2GACkC,SAAS,+HAChB,SAAS;AAAA,MAAA;AAAA,IAEjH;AAEA,UAAM,kBACJ,KAAK,OAAO,WAAW,mBAAmB;AAC5C,QAAI,oBAAoB,cAAc;AACpC,YAAM;AAAA,QACJ;AAAA,+GACkB,UAAU,0EAExB,aAAa,qBACf,+FACgC,UAAU;AAAA,MAAA;AAAA,IAEhD,OAAO;AACL,UACE,KAAK,OAAO,WAAW,uCACvB,WACA;AACA,cAAM;AAAA,UACJ;AAAA,8VAG+B,SAAS,8GACZ,UAAU;AAAA,QAAA;AAAA,MAG1C,OAAO;AACL,cAAM;AAAA,UACJ;AAAA,+TAGI,aAAa,cACf;AAAA,QAAA;AAAA,MAEN;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,WAAW,gBAAgB,OAAO;AAChD,YAAM;AAAA,QACJ;AAAA,MAAA;AAAA,IAEJ;AAEA,QAAI,KAAK,OAAO,WAAW,iBAAiB;AAC1C,YAAM,KAAK,KAAK,OAAO,UAAU,eAAe;AAAA,IAClD;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,UAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AACF;"}
|
package/dist/esm/index8.js
CHANGED
|
@@ -3,8 +3,9 @@ import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts
|
|
|
3
3
|
import { ChatOpenAI } from "@langchain/openai";
|
|
4
4
|
import { TokenUsageCallbackHandler, calculateTokenCostSync, getAllHederaCorePlugins, HederaAgentKit } from "hedera-agent-kit";
|
|
5
5
|
import { BaseAgent } from "./index7.js";
|
|
6
|
-
import { MCPClientManager } from "./
|
|
7
|
-
import { convertMCPToolToLangChain } from "./
|
|
6
|
+
import { MCPClientManager } from "./index15.js";
|
|
7
|
+
import { convertMCPToolToLangChain } from "./index16.js";
|
|
8
|
+
import { SmartMemoryManager } from "./index17.js";
|
|
8
9
|
class LangChainAgent extends BaseAgent {
|
|
9
10
|
constructor() {
|
|
10
11
|
super(...arguments);
|
|
@@ -25,7 +26,20 @@ class LangChainAgent extends BaseAgent {
|
|
|
25
26
|
if (this.config.mcp?.servers && this.config.mcp.servers.length > 0) {
|
|
26
27
|
await this.initializeMCP();
|
|
27
28
|
}
|
|
29
|
+
this.smartMemory = new SmartMemoryManager({
|
|
30
|
+
modelName,
|
|
31
|
+
maxTokens: 9e4,
|
|
32
|
+
reserveTokens: 1e4,
|
|
33
|
+
storageLimit: 1e3
|
|
34
|
+
});
|
|
35
|
+
this.logger.info("SmartMemoryManager initialized:", {
|
|
36
|
+
modelName,
|
|
37
|
+
toolsCount: this.tools.length,
|
|
38
|
+
maxTokens: 9e4,
|
|
39
|
+
reserveTokens: 1e4
|
|
40
|
+
});
|
|
28
41
|
this.systemMessage = this.buildSystemPrompt();
|
|
42
|
+
this.smartMemory.setSystemPrompt(this.systemMessage);
|
|
29
43
|
await this.createExecutor();
|
|
30
44
|
this.initialized = true;
|
|
31
45
|
this.logger.info("LangChain Hedera agent initialized");
|
|
@@ -35,19 +49,49 @@ class LangChainAgent extends BaseAgent {
|
|
|
35
49
|
}
|
|
36
50
|
}
|
|
37
51
|
async chat(message, context) {
|
|
38
|
-
if (!this.initialized || !this.executor) {
|
|
52
|
+
if (!this.initialized || !this.executor || !this.smartMemory) {
|
|
39
53
|
throw new Error("Agent not initialized. Call boot() first.");
|
|
40
54
|
}
|
|
41
55
|
try {
|
|
56
|
+
this.logger.info("LangChainAgent.chat called with:", { message, contextLength: context?.messages?.length || 0 });
|
|
57
|
+
if (context?.messages && context.messages.length > 0) {
|
|
58
|
+
this.smartMemory.clear();
|
|
59
|
+
for (const msg of context.messages) {
|
|
60
|
+
this.smartMemory.addMessage(msg);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const { HumanMessage } = await import("@langchain/core/messages");
|
|
64
|
+
this.smartMemory.addMessage(new HumanMessage(message));
|
|
65
|
+
const memoryStats = this.smartMemory.getMemoryStats();
|
|
66
|
+
this.logger.info("Memory stats before execution:", {
|
|
67
|
+
totalMessages: memoryStats.totalActiveMessages,
|
|
68
|
+
currentTokens: memoryStats.currentTokenCount,
|
|
69
|
+
maxTokens: memoryStats.maxTokens,
|
|
70
|
+
usagePercentage: memoryStats.usagePercentage,
|
|
71
|
+
toolsCount: this.tools.length
|
|
72
|
+
});
|
|
42
73
|
const result = await this.executor.invoke({
|
|
43
74
|
input: message,
|
|
44
|
-
chat_history:
|
|
75
|
+
chat_history: this.smartMemory.getMessages()
|
|
45
76
|
});
|
|
77
|
+
this.logger.info("LangChainAgent executor result:", result);
|
|
46
78
|
let response = {
|
|
47
79
|
output: result.output || "",
|
|
48
80
|
message: result.output || "",
|
|
49
|
-
notes: []
|
|
81
|
+
notes: [],
|
|
82
|
+
intermediateSteps: result.intermediateSteps
|
|
50
83
|
};
|
|
84
|
+
if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {
|
|
85
|
+
const toolCalls = result.intermediateSteps.map((step, index) => ({
|
|
86
|
+
id: `call_${index}`,
|
|
87
|
+
name: step.action?.tool || "unknown",
|
|
88
|
+
args: step.action?.toolInput || {},
|
|
89
|
+
output: typeof step.observation === "string" ? step.observation : JSON.stringify(step.observation)
|
|
90
|
+
}));
|
|
91
|
+
if (toolCalls.length > 0) {
|
|
92
|
+
response.tool_calls = toolCalls;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
51
95
|
const parsedSteps = result?.intermediateSteps?.[0]?.observation;
|
|
52
96
|
if (parsedSteps && typeof parsedSteps === "string" && this.isJSON(parsedSteps)) {
|
|
53
97
|
try {
|
|
@@ -60,6 +104,10 @@ class LangChainAgent extends BaseAgent {
|
|
|
60
104
|
if (!response.output || response.output.trim() === "") {
|
|
61
105
|
response.output = "Agent action complete.";
|
|
62
106
|
}
|
|
107
|
+
if (response.output) {
|
|
108
|
+
const { AIMessage } = await import("@langchain/core/messages");
|
|
109
|
+
this.smartMemory.addMessage(new AIMessage(response.output));
|
|
110
|
+
}
|
|
63
111
|
if (this.tokenTracker) {
|
|
64
112
|
const tokenUsage = this.tokenTracker.getLatestTokenUsage();
|
|
65
113
|
if (tokenUsage) {
|
|
@@ -67,8 +115,20 @@ class LangChainAgent extends BaseAgent {
|
|
|
67
115
|
response.cost = calculateTokenCostSync(tokenUsage);
|
|
68
116
|
}
|
|
69
117
|
}
|
|
118
|
+
const finalMemoryStats = this.smartMemory.getMemoryStats();
|
|
119
|
+
response.metadata = {
|
|
120
|
+
...response.metadata,
|
|
121
|
+
memoryStats: {
|
|
122
|
+
activeMessages: finalMemoryStats.totalActiveMessages,
|
|
123
|
+
tokenUsage: finalMemoryStats.currentTokenCount,
|
|
124
|
+
maxTokens: finalMemoryStats.maxTokens,
|
|
125
|
+
usagePercentage: finalMemoryStats.usagePercentage
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
this.logger.info("LangChainAgent.chat returning response:", response);
|
|
70
129
|
return response;
|
|
71
130
|
} catch (error) {
|
|
131
|
+
this.logger.error("LangChainAgent.chat error:", error);
|
|
72
132
|
return this.handleError(error);
|
|
73
133
|
}
|
|
74
134
|
}
|
|
@@ -76,6 +136,10 @@ class LangChainAgent extends BaseAgent {
|
|
|
76
136
|
if (this.mcpManager) {
|
|
77
137
|
await this.mcpManager.disconnectAll();
|
|
78
138
|
}
|
|
139
|
+
if (this.smartMemory) {
|
|
140
|
+
this.smartMemory.dispose();
|
|
141
|
+
this.smartMemory = void 0;
|
|
142
|
+
}
|
|
79
143
|
this.executor = void 0;
|
|
80
144
|
this.agentKit = void 0;
|
|
81
145
|
this.tools = [];
|
package/dist/esm/index8.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index8.js","sources":["../../src/langchain-agent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport { createOpenAIToolsAgent, AgentExecutor } from 'langchain/agents';\nimport {\n ChatPromptTemplate,\n MessagesPlaceholder,\n} from '@langchain/core/prompts';\nimport { ChatOpenAI } from '@langchain/openai';\nimport {\n calculateTokenCostSync,\n getAllHederaCorePlugins,\n HederaAgentKit,\n TokenUsageCallbackHandler,\n} from 'hedera-agent-kit';\nimport type { TokenUsage, CostCalculation } from 'hedera-agent-kit';\nimport {\n BaseAgent,\n type ConversationContext,\n type ChatResponse,\n type OperationalMode,\n type UsageStats,\n} from './base-agent';\nimport { MCPClientManager } from './mcp/MCPClientManager';\nimport { convertMCPToolToLangChain } from './mcp/adapters/langchain';\n\nexport class LangChainAgent extends BaseAgent {\n private executor: AgentExecutor | undefined;\n private systemMessage = '';\n private mcpManager?: MCPClientManager;\n\n async boot(): Promise<void> {\n if (this.initialized) {\n this.logger.warn('Agent already initialized');\n return;\n }\n\n try {\n this.agentKit = await this.createAgentKit();\n await this.agentKit.initialize();\n\n const modelName =\n this.config.ai?.modelName ||\n process.env.OPENAI_MODEL_NAME ||\n 'gpt-4o-mini';\n this.tokenTracker = new TokenUsageCallbackHandler(modelName);\n\n const allTools = this.agentKit.getAggregatedLangChainTools();\n this.tools = this.filterTools(allTools);\n\n if (this.config.mcp?.servers && this.config.mcp.servers.length > 0) {\n await this.initializeMCP();\n }\n\n this.systemMessage = this.buildSystemPrompt();\n\n await this.createExecutor();\n\n this.initialized = true;\n this.logger.info('LangChain Hedera agent initialized');\n } catch (error) {\n this.logger.error('Failed to initialize agent:', error);\n throw error;\n }\n }\n\n async chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse> {\n if (!this.initialized || !this.executor) {\n throw new Error('Agent not initialized. Call boot() first.');\n }\n\n try {\n const result = await this.executor.invoke({\n input: message,\n chat_history: context?.messages || [],\n });\n\n let response: ChatResponse = {\n output: result.output || '',\n message: result.output || '',\n notes: [],\n };\n\n const parsedSteps = result?.intermediateSteps?.[0]?.observation;\n if (\n parsedSteps &&\n typeof parsedSteps === 'string' &&\n this.isJSON(parsedSteps)\n ) {\n try {\n const parsed = JSON.parse(parsedSteps);\n response = { ...response, ...parsed };\n } catch (error) {\n this.logger.error('Error parsing intermediate steps:', error);\n }\n }\n\n if (!response.output || response.output.trim() === '') {\n response.output = 'Agent action complete.';\n }\n\n if (this.tokenTracker) {\n const tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n response.tokenUsage = tokenUsage;\n response.cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n return response;\n } catch (error) {\n return this.handleError(error);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.mcpManager) {\n await this.mcpManager.disconnectAll();\n }\n\n this.executor = undefined;\n this.agentKit = undefined;\n this.tools = [];\n this.initialized = false;\n this.logger.info('Agent cleaned up');\n }\n\n switchMode(mode: OperationalMode): void {\n if (this.config.execution) {\n this.config.execution.operationalMode = mode;\n } else {\n this.config.execution = { operationalMode: mode };\n }\n\n if (this.agentKit) {\n this.agentKit.operationalMode = mode;\n }\n\n this.systemMessage = this.buildSystemPrompt();\n this.logger.info(`Operational mode switched to: ${mode}`);\n }\n\n getUsageStats(): UsageStats {\n if (!this.tokenTracker) {\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: { totalCost: 0 } as CostCalculation,\n };\n }\n\n const usage = this.tokenTracker.getTotalTokenUsage();\n const cost = calculateTokenCostSync(usage);\n return { ...usage, cost };\n }\n\n getUsageLog(): UsageStats[] {\n if (!this.tokenTracker) {\n return [];\n }\n\n return this.tokenTracker.getTokenUsageHistory().map((usage) => ({\n ...usage,\n cost: calculateTokenCostSync(usage),\n }));\n }\n\n clearUsageStats(): void {\n if (this.tokenTracker) {\n this.tokenTracker.reset();\n this.logger.info('Usage statistics cleared');\n }\n }\n\n private async createAgentKit(): Promise<HederaAgentKit> {\n const corePlugins = getAllHederaCorePlugins();\n const extensionPlugins = this.config.extensions?.plugins || [];\n const plugins = [...corePlugins, ...extensionPlugins];\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n const modelName = this.config.ai?.modelName || 'gpt-4o';\n\n return new HederaAgentKit(\n this.config.signer,\n { plugins },\n operationalMode,\n this.config.execution?.userAccountId,\n this.config.execution?.scheduleUserTransactionsInBytesMode ?? true,\n undefined,\n modelName,\n this.config.extensions?.mirrorConfig,\n this.config.debug?.silent ?? false\n );\n }\n\n private async createExecutor(): Promise<void> {\n let llm: BaseChatModel;\n if (this.config.ai?.provider && this.config.ai.provider.getModel) {\n llm = this.config.ai.provider.getModel() as BaseChatModel;\n } else if (this.config.ai?.llm) {\n llm = this.config.ai.llm as BaseChatModel;\n } else {\n const apiKey = this.config.ai?.apiKey || process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new Error('OpenAI API key required');\n }\n\n llm = new ChatOpenAI({\n apiKey,\n modelName: this.config.ai?.modelName || 'gpt-4o-mini',\n temperature: this.config.ai?.temperature ?? 0.1,\n callbacks: this.tokenTracker ? [this.tokenTracker] : [],\n });\n }\n\n const prompt = ChatPromptTemplate.fromMessages([\n ['system', this.systemMessage],\n new MessagesPlaceholder('chat_history'),\n ['human', '{input}'],\n new MessagesPlaceholder('agent_scratchpad'),\n ]);\n\n const langchainTools = this.tools as unknown as StructuredTool[];\n\n const agent = await createOpenAIToolsAgent({\n llm,\n tools: langchainTools,\n prompt,\n });\n\n this.executor = new AgentExecutor({\n agent,\n tools: langchainTools,\n verbose: this.config.debug?.verbose ?? false,\n returnIntermediateSteps: true,\n });\n }\n\n private handleError(error: unknown): ChatResponse {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n this.logger.error('Chat error:', error);\n\n let tokenUsage: TokenUsage | undefined;\n let cost: CostCalculation | undefined;\n\n if (this.tokenTracker) {\n tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n const errorResponse: ChatResponse = {\n output: 'Sorry, I encountered an error processing your request.',\n message: 'Error processing request.',\n error: errorMessage,\n notes: [],\n };\n\n if (tokenUsage) {\n errorResponse.tokenUsage = tokenUsage;\n }\n\n if (cost) {\n errorResponse.cost = cost;\n }\n\n return errorResponse;\n }\n\n private async initializeMCP(): Promise<void> {\n this.mcpManager = new MCPClientManager(this.logger);\n\n for (const serverConfig of this.config.mcp!.servers!) {\n if (serverConfig.autoConnect === false) {\n this.logger.info(\n `Skipping MCP server ${serverConfig.name} (autoConnect=false)`\n );\n continue;\n }\n\n const status = await this.mcpManager.connectServer(serverConfig);\n\n if (status.connected) {\n this.logger.info(\n `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`\n );\n\n for (const mcpTool of status.tools) {\n const langchainTool = convertMCPToolToLangChain(\n mcpTool,\n this.mcpManager,\n serverConfig\n );\n this.tools.push(langchainTool);\n }\n } else {\n this.logger.error(\n `Failed to connect to MCP server ${status.serverName}: ${status.error}`\n );\n }\n }\n }\n\n /**\n * Check if a string is valid JSON\n */\n private isJSON(str: string): boolean {\n if (typeof str !== 'string') return false;\n\n const trimmed = str.trim();\n if (!trimmed) return false;\n\n if (\n !(trimmed.startsWith('{') && trimmed.endsWith('}')) &&\n !(trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n return false;\n }\n\n try {\n JSON.parse(trimmed);\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index8.js","sources":["../../src/langchain-agent.ts"],"sourcesContent":["import type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { StructuredTool } from '@langchain/core/tools';\nimport { createOpenAIToolsAgent, AgentExecutor } from 'langchain/agents';\nimport {\n ChatPromptTemplate,\n MessagesPlaceholder,\n} from '@langchain/core/prompts';\nimport { ChatOpenAI } from '@langchain/openai';\nimport {\n calculateTokenCostSync,\n getAllHederaCorePlugins,\n HederaAgentKit,\n TokenUsageCallbackHandler,\n} from 'hedera-agent-kit';\nimport type { TokenUsage, CostCalculation } from 'hedera-agent-kit';\nimport {\n BaseAgent,\n type ConversationContext,\n type ChatResponse,\n type OperationalMode,\n type UsageStats,\n} from './base-agent';\nimport { MCPClientManager } from './mcp/MCPClientManager';\nimport { convertMCPToolToLangChain } from './mcp/adapters/langchain';\nimport { SmartMemoryManager } from './memory/SmartMemoryManager';\n\nexport class LangChainAgent extends BaseAgent {\n private executor: AgentExecutor | undefined;\n private systemMessage = '';\n private mcpManager?: MCPClientManager;\n private smartMemory: SmartMemoryManager | undefined;\n\n async boot(): Promise<void> {\n if (this.initialized) {\n this.logger.warn('Agent already initialized');\n return;\n }\n\n try {\n this.agentKit = await this.createAgentKit();\n await this.agentKit.initialize();\n\n const modelName =\n this.config.ai?.modelName ||\n process.env.OPENAI_MODEL_NAME ||\n 'gpt-4o-mini';\n this.tokenTracker = new TokenUsageCallbackHandler(modelName);\n\n const allTools = this.agentKit.getAggregatedLangChainTools();\n this.tools = this.filterTools(allTools);\n\n if (this.config.mcp?.servers && this.config.mcp.servers.length > 0) {\n await this.initializeMCP();\n }\n\n this.smartMemory = new SmartMemoryManager({\n modelName,\n maxTokens: 90000,\n reserveTokens: 10000,\n storageLimit: 1000\n });\n \n this.logger.info('SmartMemoryManager initialized:', {\n modelName,\n toolsCount: this.tools.length,\n maxTokens: 90000,\n reserveTokens: 10000\n });\n\n this.systemMessage = this.buildSystemPrompt();\n \n // Set the system prompt in smart memory\n this.smartMemory.setSystemPrompt(this.systemMessage);\n\n await this.createExecutor();\n\n this.initialized = true;\n this.logger.info('LangChain Hedera agent initialized');\n } catch (error) {\n this.logger.error('Failed to initialize agent:', error);\n throw error;\n }\n }\n\n async chat(\n message: string,\n context?: ConversationContext\n ): Promise<ChatResponse> {\n if (!this.initialized || !this.executor || !this.smartMemory) {\n throw new Error('Agent not initialized. Call boot() first.');\n }\n\n try {\n this.logger.info('LangChainAgent.chat called with:', { message, contextLength: context?.messages?.length || 0 });\n \n // If context is provided, populate smart memory with previous messages\n if (context?.messages && context.messages.length > 0) {\n // Clear existing memory and add messages from context\n this.smartMemory.clear();\n \n for (const msg of context.messages) {\n this.smartMemory.addMessage(msg);\n }\n }\n \n // Add the current user message to memory\n const { HumanMessage } = await import('@langchain/core/messages');\n this.smartMemory.addMessage(new HumanMessage(message));\n \n const memoryStats = this.smartMemory.getMemoryStats();\n this.logger.info('Memory stats before execution:', {\n totalMessages: memoryStats.totalActiveMessages,\n currentTokens: memoryStats.currentTokenCount,\n maxTokens: memoryStats.maxTokens,\n usagePercentage: memoryStats.usagePercentage,\n toolsCount: this.tools.length\n });\n \n const result = await this.executor.invoke({\n input: message,\n chat_history: this.smartMemory.getMessages(),\n });\n\n this.logger.info('LangChainAgent executor result:', result);\n\n let response: ChatResponse = {\n output: result.output || '',\n message: result.output || '',\n notes: [],\n intermediateSteps: result.intermediateSteps,\n };\n\n // Extract tool calls from intermediate steps\n if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {\n const toolCalls = result.intermediateSteps.map((step: any, index: number) => ({\n id: `call_${index}`,\n name: step.action?.tool || 'unknown',\n args: step.action?.toolInput || {},\n output: typeof step.observation === 'string' ? step.observation : JSON.stringify(step.observation)\n }));\n \n if (toolCalls.length > 0) {\n response.tool_calls = toolCalls;\n }\n }\n\n const parsedSteps = result?.intermediateSteps?.[0]?.observation;\n if (\n parsedSteps &&\n typeof parsedSteps === 'string' &&\n this.isJSON(parsedSteps)\n ) {\n try {\n const parsed = JSON.parse(parsedSteps);\n response = { ...response, ...parsed };\n } catch (error) {\n this.logger.error('Error parsing intermediate steps:', error);\n }\n }\n\n if (!response.output || response.output.trim() === '') {\n response.output = 'Agent action complete.';\n }\n\n // Add the AI response to memory\n if (response.output) {\n const { AIMessage } = await import('@langchain/core/messages');\n this.smartMemory.addMessage(new AIMessage(response.output));\n }\n\n if (this.tokenTracker) {\n const tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n response.tokenUsage = tokenUsage;\n response.cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n const finalMemoryStats = this.smartMemory.getMemoryStats();\n response.metadata = {\n ...response.metadata,\n memoryStats: {\n activeMessages: finalMemoryStats.totalActiveMessages,\n tokenUsage: finalMemoryStats.currentTokenCount,\n maxTokens: finalMemoryStats.maxTokens,\n usagePercentage: finalMemoryStats.usagePercentage\n }\n };\n\n this.logger.info('LangChainAgent.chat returning response:', response);\n return response;\n } catch (error) {\n this.logger.error('LangChainAgent.chat error:', error);\n return this.handleError(error);\n }\n }\n\n async shutdown(): Promise<void> {\n if (this.mcpManager) {\n await this.mcpManager.disconnectAll();\n }\n\n if (this.smartMemory) {\n this.smartMemory.dispose();\n this.smartMemory = undefined;\n }\n\n this.executor = undefined;\n this.agentKit = undefined;\n this.tools = [];\n this.initialized = false;\n this.logger.info('Agent cleaned up');\n }\n\n switchMode(mode: OperationalMode): void {\n if (this.config.execution) {\n this.config.execution.operationalMode = mode;\n } else {\n this.config.execution = { operationalMode: mode };\n }\n\n if (this.agentKit) {\n this.agentKit.operationalMode = mode;\n }\n\n this.systemMessage = this.buildSystemPrompt();\n this.logger.info(`Operational mode switched to: ${mode}`);\n }\n\n getUsageStats(): UsageStats {\n if (!this.tokenTracker) {\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n cost: { totalCost: 0 } as CostCalculation,\n };\n }\n\n const usage = this.tokenTracker.getTotalTokenUsage();\n const cost = calculateTokenCostSync(usage);\n return { ...usage, cost };\n }\n\n getUsageLog(): UsageStats[] {\n if (!this.tokenTracker) {\n return [];\n }\n\n return this.tokenTracker.getTokenUsageHistory().map((usage) => ({\n ...usage,\n cost: calculateTokenCostSync(usage),\n }));\n }\n\n clearUsageStats(): void {\n if (this.tokenTracker) {\n this.tokenTracker.reset();\n this.logger.info('Usage statistics cleared');\n }\n }\n\n\n private async createAgentKit(): Promise<HederaAgentKit> {\n const corePlugins = getAllHederaCorePlugins();\n const extensionPlugins = this.config.extensions?.plugins || [];\n const plugins = [...corePlugins, ...extensionPlugins];\n\n const operationalMode =\n this.config.execution?.operationalMode || 'returnBytes';\n const modelName = this.config.ai?.modelName || 'gpt-4o';\n\n return new HederaAgentKit(\n this.config.signer,\n { plugins },\n operationalMode,\n this.config.execution?.userAccountId,\n this.config.execution?.scheduleUserTransactionsInBytesMode ?? true,\n undefined,\n modelName,\n this.config.extensions?.mirrorConfig,\n this.config.debug?.silent ?? false\n );\n }\n\n private async createExecutor(): Promise<void> {\n let llm: BaseChatModel;\n if (this.config.ai?.provider && this.config.ai.provider.getModel) {\n llm = this.config.ai.provider.getModel() as BaseChatModel;\n } else if (this.config.ai?.llm) {\n llm = this.config.ai.llm as BaseChatModel;\n } else {\n const apiKey = this.config.ai?.apiKey || process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new Error('OpenAI API key required');\n }\n\n llm = new ChatOpenAI({\n apiKey,\n modelName: this.config.ai?.modelName || 'gpt-4o-mini',\n temperature: this.config.ai?.temperature ?? 0.1,\n callbacks: this.tokenTracker ? [this.tokenTracker] : [],\n });\n }\n\n const prompt = ChatPromptTemplate.fromMessages([\n ['system', this.systemMessage],\n new MessagesPlaceholder('chat_history'),\n ['human', '{input}'],\n new MessagesPlaceholder('agent_scratchpad'),\n ]);\n\n const langchainTools = this.tools as unknown as StructuredTool[];\n\n const agent = await createOpenAIToolsAgent({\n llm,\n tools: langchainTools,\n prompt,\n });\n\n // Create executor without memory - we handle memory manually with SmartMemoryManager\n this.executor = new AgentExecutor({\n agent,\n tools: langchainTools,\n verbose: this.config.debug?.verbose ?? false,\n returnIntermediateSteps: true,\n });\n }\n\n private handleError(error: unknown): ChatResponse {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n this.logger.error('Chat error:', error);\n\n let tokenUsage: TokenUsage | undefined;\n let cost: CostCalculation | undefined;\n\n if (this.tokenTracker) {\n tokenUsage = this.tokenTracker.getLatestTokenUsage();\n if (tokenUsage) {\n cost = calculateTokenCostSync(tokenUsage);\n }\n }\n\n const errorResponse: ChatResponse = {\n output: 'Sorry, I encountered an error processing your request.',\n message: 'Error processing request.',\n error: errorMessage,\n notes: [],\n };\n\n if (tokenUsage) {\n errorResponse.tokenUsage = tokenUsage;\n }\n\n if (cost) {\n errorResponse.cost = cost;\n }\n\n return errorResponse;\n }\n\n private async initializeMCP(): Promise<void> {\n this.mcpManager = new MCPClientManager(this.logger);\n\n for (const serverConfig of this.config.mcp!.servers!) {\n if (serverConfig.autoConnect === false) {\n this.logger.info(\n `Skipping MCP server ${serverConfig.name} (autoConnect=false)`\n );\n continue;\n }\n\n const status = await this.mcpManager.connectServer(serverConfig);\n\n if (status.connected) {\n this.logger.info(\n `Connected to MCP server ${status.serverName} with ${status.tools.length} tools`\n );\n\n for (const mcpTool of status.tools) {\n const langchainTool = convertMCPToolToLangChain(\n mcpTool,\n this.mcpManager,\n serverConfig\n );\n this.tools.push(langchainTool);\n }\n } else {\n this.logger.error(\n `Failed to connect to MCP server ${status.serverName}: ${status.error}`\n );\n }\n }\n }\n\n /**\n * Check if a string is valid JSON\n */\n private isJSON(str: string): boolean {\n if (typeof str !== 'string') return false;\n\n const trimmed = str.trim();\n if (!trimmed) return false;\n\n if (\n !(trimmed.startsWith('{') && trimmed.endsWith('}')) &&\n !(trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n return false;\n }\n\n try {\n JSON.parse(trimmed);\n return true;\n } catch {\n return false;\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,12 @@ export interface ChatResponse {
|
|
|
67
67
|
tokenUsage?: TokenUsage;
|
|
68
68
|
cost?: CostCalculation;
|
|
69
69
|
metadata?: Record<string, unknown>;
|
|
70
|
+
tool_calls?: Array<{
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
args: Record<string, unknown>;
|
|
74
|
+
output?: string;
|
|
75
|
+
}>;
|
|
70
76
|
[key: string]: unknown;
|
|
71
77
|
}
|
|
72
78
|
export interface UsageStats extends TokenUsage {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ContentReference, ReferenceId } from '../types/content-reference';
|
|
2
|
+
import { ContentStorage } from '../memory/ContentStorage';
|
|
3
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
4
|
+
|
|
5
|
+
export interface ReferenceContext {
|
|
6
|
+
reference: ContentReference;
|
|
7
|
+
displayedAt: Date;
|
|
8
|
+
lastAccessedAt: Date;
|
|
9
|
+
contextId: string;
|
|
10
|
+
conversationTurn: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ReferenceDisplayOptions {
|
|
13
|
+
maxPreviewLength?: number;
|
|
14
|
+
showMetadata?: boolean;
|
|
15
|
+
showSize?: boolean;
|
|
16
|
+
includeActions?: boolean;
|
|
17
|
+
format?: 'inline' | 'card' | 'compact';
|
|
18
|
+
}
|
|
19
|
+
export interface DisplayResult {
|
|
20
|
+
displayText: string;
|
|
21
|
+
hasValidReference: boolean;
|
|
22
|
+
contextId?: string;
|
|
23
|
+
suggestedActions?: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Manages content references within agent conversation context
|
|
27
|
+
* Tracks reference usage, provides display formatting, and handles reference validation
|
|
28
|
+
*/
|
|
29
|
+
export declare class ReferenceContextManager {
|
|
30
|
+
private activeReferences;
|
|
31
|
+
private contentStorage;
|
|
32
|
+
private logger;
|
|
33
|
+
private conversationTurn;
|
|
34
|
+
constructor(contentStorage: ContentStorage, logger: Logger);
|
|
35
|
+
/**
|
|
36
|
+
* Add a reference to the current conversation context
|
|
37
|
+
*/
|
|
38
|
+
addReference(reference: ContentReference): string;
|
|
39
|
+
/**
|
|
40
|
+
* Generate display text for a content reference
|
|
41
|
+
*/
|
|
42
|
+
displayReference(reference: ContentReference, options?: ReferenceDisplayOptions): Promise<DisplayResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Get the most recent reference for "inscribe it" commands
|
|
45
|
+
*/
|
|
46
|
+
getMostRecentReference(): ContentReference | null;
|
|
47
|
+
/**
|
|
48
|
+
* Get reference by context ID
|
|
49
|
+
*/
|
|
50
|
+
getReferenceByContextId(contextId: string): ContentReference | null;
|
|
51
|
+
/**
|
|
52
|
+
* Validate all active references and remove invalid ones
|
|
53
|
+
*/
|
|
54
|
+
validateReferences(): Promise<{
|
|
55
|
+
valid: number;
|
|
56
|
+
invalid: number;
|
|
57
|
+
removed: ReferenceId[];
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Clear old references based on age and usage
|
|
61
|
+
*/
|
|
62
|
+
cleanupOldReferences(maxAgeMs?: number): number;
|
|
63
|
+
/**
|
|
64
|
+
* Get current context statistics
|
|
65
|
+
*/
|
|
66
|
+
getContextStats(): {
|
|
67
|
+
activeReferences: number;
|
|
68
|
+
conversationTurn: number;
|
|
69
|
+
oldestReference: number | null;
|
|
70
|
+
mostRecentReference: number | null;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Clear all references from context
|
|
74
|
+
*/
|
|
75
|
+
clear(): void;
|
|
76
|
+
private formatCardReference;
|
|
77
|
+
private formatInlineReference;
|
|
78
|
+
private formatCompactReference;
|
|
79
|
+
private formatInvalidReference;
|
|
80
|
+
private formatErrorReference;
|
|
81
|
+
private truncateText;
|
|
82
|
+
private getOldestReferenceAge;
|
|
83
|
+
private getMostRecentReferenceAge;
|
|
84
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ContentReference, ReferenceId } from '../types/content-reference';
|
|
2
|
+
import { ReferenceContextManager, ReferenceDisplayOptions } from './ReferenceContextManager';
|
|
3
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
4
|
+
|
|
5
|
+
export interface ResponseProcessingOptions {
|
|
6
|
+
autoDisplayReferences?: boolean;
|
|
7
|
+
displayOptions?: ReferenceDisplayOptions;
|
|
8
|
+
includeReferenceInstructions?: boolean;
|
|
9
|
+
contextualizeReferences?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ProcessedResponse {
|
|
12
|
+
content: string;
|
|
13
|
+
hasReferences: boolean;
|
|
14
|
+
referenceCount: number;
|
|
15
|
+
contextIds: string[];
|
|
16
|
+
suggestedActions: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface ReferenceDetectionResult {
|
|
19
|
+
hasReferences: boolean;
|
|
20
|
+
references: Array<{
|
|
21
|
+
reference: ContentReference;
|
|
22
|
+
position: number;
|
|
23
|
+
originalText: string;
|
|
24
|
+
}>;
|
|
25
|
+
plainReferences: Array<{
|
|
26
|
+
referenceId: ReferenceId;
|
|
27
|
+
position: number;
|
|
28
|
+
originalText: string;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Processes agent responses to detect and display content references
|
|
33
|
+
* Handles both structured references and plain reference IDs
|
|
34
|
+
*/
|
|
35
|
+
export declare class ReferenceResponseProcessor {
|
|
36
|
+
private contextManager;
|
|
37
|
+
private logger;
|
|
38
|
+
constructor(contextManager: ReferenceContextManager, logger: Logger);
|
|
39
|
+
/**
|
|
40
|
+
* Process an agent response to handle content references
|
|
41
|
+
*/
|
|
42
|
+
processResponse(responseContent: string, options?: ResponseProcessingOptions): Promise<ProcessedResponse>;
|
|
43
|
+
/**
|
|
44
|
+
* Detect references in response content
|
|
45
|
+
*/
|
|
46
|
+
private detectReferences;
|
|
47
|
+
/**
|
|
48
|
+
* Create a preview from content buffer
|
|
49
|
+
*/
|
|
50
|
+
private createPreviewFromContent;
|
|
51
|
+
/**
|
|
52
|
+
* Validate reference ID format
|
|
53
|
+
*/
|
|
54
|
+
private isValidReferenceId;
|
|
55
|
+
/**
|
|
56
|
+
* Get reference context statistics
|
|
57
|
+
*/
|
|
58
|
+
getContextStats(): {
|
|
59
|
+
activeReferences: number;
|
|
60
|
+
conversationTurn: number;
|
|
61
|
+
oldestReference: number | null;
|
|
62
|
+
mostRecentReference: number | null;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Validate all references in context
|
|
66
|
+
*/
|
|
67
|
+
validateAllReferences(): Promise<{
|
|
68
|
+
valid: number;
|
|
69
|
+
invalid: number;
|
|
70
|
+
removed: ReferenceId[];
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Clean up old references
|
|
74
|
+
*/
|
|
75
|
+
cleanupOldReferences(maxAgeMs?: number): number;
|
|
76
|
+
}
|
|
@@ -50,6 +50,7 @@ export declare class ConversationalAgent {
|
|
|
50
50
|
stateManager: IStateManager;
|
|
51
51
|
private options;
|
|
52
52
|
private logger;
|
|
53
|
+
private contentStoreManager?;
|
|
53
54
|
constructor(options: ConversationalAgentOptions);
|
|
54
55
|
/**
|
|
55
56
|
* Initialize the conversational agent with Hedera network connection and AI configuration
|
|
@@ -90,6 +91,35 @@ export declare class ConversationalAgent {
|
|
|
90
91
|
type: 'human' | 'ai';
|
|
91
92
|
content: string;
|
|
92
93
|
}[]): Promise<ChatResponse>;
|
|
94
|
+
/**
|
|
95
|
+
* Validates initialization options and throws if required fields are missing.
|
|
96
|
+
*
|
|
97
|
+
* @param accountId - The Hedera account ID
|
|
98
|
+
* @param privateKey - The private key for the account
|
|
99
|
+
* @throws {Error} If required fields are missing
|
|
100
|
+
*/
|
|
101
|
+
private validateOptions;
|
|
102
|
+
/**
|
|
103
|
+
* Prepares the list of plugins to use based on configuration.
|
|
104
|
+
*
|
|
105
|
+
* @returns Array of plugins to initialize with the agent
|
|
106
|
+
*/
|
|
107
|
+
private preparePlugins;
|
|
108
|
+
/**
|
|
109
|
+
* Creates the agent configuration object.
|
|
110
|
+
*
|
|
111
|
+
* @param serverSigner - The server signer instance
|
|
112
|
+
* @param llm - The language model instance
|
|
113
|
+
* @param allPlugins - Array of plugins to use
|
|
114
|
+
* @returns Configuration object for creating the agent
|
|
115
|
+
*/
|
|
116
|
+
private createAgentConfig;
|
|
117
|
+
/**
|
|
118
|
+
* Configures the HCS-10 plugin with the state manager.
|
|
119
|
+
*
|
|
120
|
+
* @param allPlugins - Array of all plugins
|
|
121
|
+
*/
|
|
122
|
+
private configureHCS10Plugin;
|
|
93
123
|
/**
|
|
94
124
|
* Create a ConversationalAgent with specific plugins enabled
|
|
95
125
|
*/
|
|
@@ -146,4 +176,8 @@ export declare class ConversationalAgent {
|
|
|
146
176
|
* @returns {Promise<PrivateKey>} The appropriate PrivateKey instance
|
|
147
177
|
*/
|
|
148
178
|
private detectPrivateKeyType;
|
|
179
|
+
/**
|
|
180
|
+
* Clean up resources
|
|
181
|
+
*/
|
|
182
|
+
cleanup(): Promise<void>;
|
|
149
183
|
}
|
|
@@ -4,6 +4,7 @@ export declare class LangChainAgent extends BaseAgent {
|
|
|
4
4
|
private executor;
|
|
5
5
|
private systemMessage;
|
|
6
6
|
private mcpManager?;
|
|
7
|
+
private smartMemory;
|
|
7
8
|
boot(): Promise<void>;
|
|
8
9
|
chat(message: string, context?: ConversationContext): Promise<ChatResponse>;
|
|
9
10
|
shutdown(): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ContentStorage } from '../memory/ContentStorage';
|
|
2
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
3
|
+
|
|
4
|
+
export interface MCPResponseContent {
|
|
5
|
+
content: unknown;
|
|
6
|
+
type: 'text' | 'image' | 'resource' | 'text[]' | 'image[]';
|
|
7
|
+
sizeBytes: number;
|
|
8
|
+
mimeType?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ProcessedResponse {
|
|
11
|
+
content: unknown;
|
|
12
|
+
wasProcessed: boolean;
|
|
13
|
+
referenceCreated?: boolean;
|
|
14
|
+
referenceId?: string;
|
|
15
|
+
originalSize?: number;
|
|
16
|
+
errors?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface ContentAnalysis {
|
|
19
|
+
shouldProcess: boolean;
|
|
20
|
+
contents: MCPResponseContent[];
|
|
21
|
+
totalSize: number;
|
|
22
|
+
largestContentSize: number;
|
|
23
|
+
}
|
|
24
|
+
export declare class MCPContentProcessor {
|
|
25
|
+
private contentStorage;
|
|
26
|
+
private logger;
|
|
27
|
+
constructor(contentStorage: ContentStorage, logger: Logger);
|
|
28
|
+
analyzeResponse(response: unknown): ContentAnalysis;
|
|
29
|
+
processResponse(response: unknown, serverName: string, toolName: string): Promise<ProcessedResponse>;
|
|
30
|
+
private extractContentFromResponse;
|
|
31
|
+
private createReferencedResponse;
|
|
32
|
+
private createLightweightReference;
|
|
33
|
+
private replaceContentInResponse;
|
|
34
|
+
private detectMimeType;
|
|
35
|
+
private mapMimeTypeToContentType;
|
|
36
|
+
private deepClone;
|
|
37
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MCPServerConfig, MCPToolInfo, MCPConnectionStatus } from './types';
|
|
2
2
|
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
3
|
+
import { ContentStorage } from '../memory/ContentStorage';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Manages connections to MCP servers and tool discovery
|
|
@@ -8,7 +9,8 @@ export declare class MCPClientManager {
|
|
|
8
9
|
private clients;
|
|
9
10
|
private tools;
|
|
10
11
|
private logger;
|
|
11
|
-
|
|
12
|
+
private contentProcessor?;
|
|
13
|
+
constructor(logger: Logger, contentStorage?: ContentStorage);
|
|
12
14
|
/**
|
|
13
15
|
* Connect to an MCP server and discover its tools
|
|
14
16
|
*/
|
|
@@ -37,4 +39,20 @@ export declare class MCPClientManager {
|
|
|
37
39
|
* Get list of connected server names
|
|
38
40
|
*/
|
|
39
41
|
getConnectedServers(): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Enable content processing with content storage
|
|
44
|
+
*/
|
|
45
|
+
enableContentProcessing(contentStorage: ContentStorage): void;
|
|
46
|
+
/**
|
|
47
|
+
* Disable content processing
|
|
48
|
+
*/
|
|
49
|
+
disableContentProcessing(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Check if content processing is enabled
|
|
52
|
+
*/
|
|
53
|
+
isContentProcessingEnabled(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Analyze a response without processing it (for testing/debugging)
|
|
56
|
+
*/
|
|
57
|
+
analyzeResponseContent(response: unknown): unknown;
|
|
40
58
|
}
|