@hashgraphonline/conversational-agent 0.1.208 → 0.1.210
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/bin/conversational-agent-cli.js +30 -0
- package/cli/readme.md +181 -0
- package/dist/cjs/base-agent.d.ts +3 -1
- package/dist/cjs/conversational-agent.d.ts +64 -13
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +6 -3
- package/dist/cjs/langchain-agent.d.ts +11 -0
- package/dist/cjs/memory/SmartMemoryManager.d.ts +65 -22
- package/dist/cjs/memory/TokenCounter.d.ts +1 -1
- package/dist/cjs/memory/index.d.ts +1 -1
- package/dist/cjs/plugins/hbar/AirdropToolWrapper.d.ts +43 -0
- package/dist/{types/plugins/hbar-transfer/HbarTransferPlugin.d.ts → cjs/plugins/hbar/HbarPlugin.d.ts} +2 -1
- package/dist/{types/plugins/hbar-transfer → cjs/plugins/hbar}/TransferHbarTool.d.ts +1 -1
- package/dist/cjs/plugins/hbar/index.d.ts +3 -0
- package/dist/cjs/plugins/index.d.ts +2 -1
- package/dist/cjs/services/EntityResolver.d.ts +26 -0
- package/dist/cjs/tools/EntityResolverTool.d.ts +104 -0
- package/dist/cjs/types/inscription.d.ts +37 -0
- package/dist/esm/index.js +16 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index12.js +121 -46
- package/dist/esm/index12.js.map +1 -1
- package/dist/esm/index13.js +177 -13
- package/dist/esm/index13.js.map +1 -1
- package/dist/esm/index14.js +599 -100
- package/dist/esm/index14.js.map +1 -1
- package/dist/esm/index15.js +426 -9
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index16.js +119 -160
- package/dist/esm/index16.js.map +1 -1
- package/dist/esm/index17.js +140 -150
- package/dist/esm/index17.js.map +1 -1
- package/dist/esm/index18.js +44 -231
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index19.js +86 -643
- package/dist/esm/index19.js.map +1 -1
- package/dist/esm/index2.js +22 -13
- package/dist/esm/index2.js.map +1 -1
- package/dist/esm/index20.js +20 -230
- package/dist/esm/index20.js.map +1 -1
- package/dist/esm/index21.js +9 -179
- package/dist/esm/index21.js.map +1 -1
- package/dist/esm/index22.js +140 -89
- package/dist/esm/index22.js.map +1 -1
- package/dist/esm/index23.js +141 -81
- package/dist/esm/index23.js.map +1 -1
- package/dist/esm/index24.js +4 -4
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index25.js +0 -8
- package/dist/esm/index25.js.map +1 -1
- package/dist/esm/index26.js +95 -0
- package/dist/esm/index26.js.map +1 -0
- package/dist/esm/index27.js +242 -0
- package/dist/esm/index27.js.map +1 -0
- package/dist/esm/index5.js +32 -19
- package/dist/esm/index5.js.map +1 -1
- package/dist/esm/index6.js +276 -37
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index7.js +2 -2
- package/dist/esm/index7.js.map +1 -1
- package/dist/esm/index8.js +124 -18
- package/dist/esm/index8.js.map +1 -1
- package/dist/types/base-agent.d.ts +3 -1
- package/dist/types/conversational-agent.d.ts +64 -13
- package/dist/types/index.d.ts +6 -3
- package/dist/types/langchain-agent.d.ts +11 -0
- package/dist/types/memory/SmartMemoryManager.d.ts +65 -22
- package/dist/types/memory/TokenCounter.d.ts +1 -1
- package/dist/types/memory/index.d.ts +1 -1
- package/dist/types/plugins/hbar/AirdropToolWrapper.d.ts +43 -0
- package/dist/{cjs/plugins/hbar-transfer/HbarTransferPlugin.d.ts → types/plugins/hbar/HbarPlugin.d.ts} +2 -1
- package/dist/{cjs/plugins/hbar-transfer → types/plugins/hbar}/TransferHbarTool.d.ts +1 -1
- package/dist/types/plugins/hbar/index.d.ts +3 -0
- package/dist/types/plugins/index.d.ts +2 -1
- package/dist/types/services/EntityResolver.d.ts +26 -0
- package/dist/types/tools/EntityResolverTool.d.ts +104 -0
- package/dist/types/types/inscription.d.ts +37 -0
- package/package.json +13 -4
- package/src/base-agent.ts +14 -9
- package/src/config/system-message.ts +11 -2
- package/src/context/ReferenceContextManager.ts +10 -5
- package/src/context/ReferenceResponseProcessor.ts +3 -4
- package/src/conversational-agent.ts +372 -57
- package/src/index.ts +19 -3
- package/src/langchain/ContentAwareAgentExecutor.ts +0 -1
- package/src/langchain-agent.ts +168 -33
- package/src/mcp/ContentProcessor.ts +11 -3
- package/src/mcp/adapters/langchain.ts +1 -10
- package/src/memory/ContentStorage.ts +2 -55
- package/src/memory/MemoryWindow.ts +4 -17
- package/src/memory/ReferenceIdGenerator.ts +4 -8
- package/src/memory/SmartMemoryManager.ts +375 -47
- package/src/memory/TokenCounter.ts +15 -22
- package/src/memory/index.ts +1 -1
- package/src/plugins/hbar/AirdropToolWrapper.ts +157 -0
- package/src/plugins/hbar/HbarPlugin.ts +86 -0
- package/src/plugins/{hbar-transfer → hbar}/TransferHbarTool.ts +3 -3
- package/src/plugins/hbar/index.ts +3 -0
- package/src/plugins/hcs-10/HCS10Plugin.ts +44 -14
- package/src/plugins/index.ts +2 -1
- package/src/services/ContentStoreManager.ts +0 -3
- package/src/services/EntityResolver.ts +135 -0
- package/src/tools/EntityResolverTool.ts +170 -0
- package/src/types/content-reference.ts +8 -8
- package/src/types/index.ts +0 -1
- package/src/types/inscription.ts +40 -0
- package/dist/cjs/plugins/hbar-transfer/index.d.ts +0 -1
- package/dist/types/plugins/hbar-transfer/index.d.ts +0 -1
- package/src/plugins/hbar-transfer/HbarTransferPlugin.ts +0 -66
- package/src/plugins/hbar-transfer/index.ts +0 -1
- /package/dist/cjs/plugins/{hbar-transfer → hbar}/AccountBuilder.d.ts +0 -0
- /package/dist/cjs/plugins/{hbar-transfer → hbar}/types.d.ts +0 -0
- /package/dist/types/plugins/{hbar-transfer → hbar}/AccountBuilder.d.ts +0 -0
- /package/dist/types/plugins/{hbar-transfer → hbar}/types.d.ts +0 -0
- /package/src/plugins/{hbar-transfer → hbar}/AccountBuilder.ts +0 -0
- /package/src/plugins/{hbar-transfer → hbar}/types.ts +0 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
class MCPContentProcessor {
|
|
2
|
+
constructor(contentStorage, logger) {
|
|
3
|
+
this.contentStorage = contentStorage;
|
|
4
|
+
this.logger = logger;
|
|
5
|
+
}
|
|
6
|
+
analyzeResponse(response) {
|
|
7
|
+
const contents = [];
|
|
8
|
+
let totalSize = 0;
|
|
9
|
+
this.extractContentFromResponse(response, contents);
|
|
10
|
+
totalSize = contents.reduce((sum, content) => sum + content.sizeBytes, 0);
|
|
11
|
+
const largestContentSize = contents.reduce((max, content) => Math.max(max, content.sizeBytes), 0);
|
|
12
|
+
const shouldProcess = contents.some(
|
|
13
|
+
(content) => this.contentStorage.shouldUseReference(
|
|
14
|
+
typeof content.content === "string" ? content.content : JSON.stringify(content.content)
|
|
15
|
+
)
|
|
16
|
+
);
|
|
17
|
+
return {
|
|
18
|
+
shouldProcess,
|
|
19
|
+
contents,
|
|
20
|
+
totalSize,
|
|
21
|
+
largestContentSize
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async processResponse(response, serverName, toolName) {
|
|
25
|
+
try {
|
|
26
|
+
const analysis = this.analyzeResponse(response);
|
|
27
|
+
if (!analysis.shouldProcess) {
|
|
28
|
+
return {
|
|
29
|
+
content: response,
|
|
30
|
+
wasProcessed: false
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const processedResponse = await this.createReferencedResponse(
|
|
34
|
+
response,
|
|
35
|
+
analysis,
|
|
36
|
+
serverName,
|
|
37
|
+
toolName
|
|
38
|
+
);
|
|
39
|
+
return processedResponse;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
this.logger.error("Error processing MCP response:", error);
|
|
42
|
+
return {
|
|
43
|
+
content: response,
|
|
44
|
+
wasProcessed: false,
|
|
45
|
+
errors: [error instanceof Error ? error.message : "Unknown processing error"]
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
extractContentFromResponse(obj, contents) {
|
|
50
|
+
if (obj === null || obj === void 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (Array.isArray(obj)) {
|
|
54
|
+
obj.forEach((item) => this.extractContentFromResponse(item, contents));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (typeof obj === "object") {
|
|
58
|
+
const record = obj;
|
|
59
|
+
if (record.type === "text" && typeof record.text === "string") {
|
|
60
|
+
contents.push({
|
|
61
|
+
content: record.text,
|
|
62
|
+
type: "text",
|
|
63
|
+
sizeBytes: Buffer.byteLength(record.text, "utf8"),
|
|
64
|
+
mimeType: this.detectMimeType(record.text)
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (record.type === "image" && typeof record.data === "string") {
|
|
69
|
+
contents.push({
|
|
70
|
+
content: record.data,
|
|
71
|
+
type: "image",
|
|
72
|
+
sizeBytes: Math.ceil(record.data.length * 0.75),
|
|
73
|
+
mimeType: record.mimeType || "image/jpeg"
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (record.type === "resource" && record.resource) {
|
|
78
|
+
const resourceStr = JSON.stringify(record.resource);
|
|
79
|
+
contents.push({
|
|
80
|
+
content: resourceStr,
|
|
81
|
+
type: "resource",
|
|
82
|
+
sizeBytes: Buffer.byteLength(resourceStr, "utf8"),
|
|
83
|
+
mimeType: "application/json"
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
Object.values(record).forEach((value) => this.extractContentFromResponse(value, contents));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (typeof obj === "string") {
|
|
91
|
+
if (obj.length > 1e3) {
|
|
92
|
+
contents.push({
|
|
93
|
+
content: obj,
|
|
94
|
+
type: "text",
|
|
95
|
+
sizeBytes: Buffer.byteLength(obj, "utf8"),
|
|
96
|
+
mimeType: this.detectMimeType(obj)
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async createReferencedResponse(originalResponse, analysis, serverName, toolName) {
|
|
102
|
+
const processedResponse = this.deepClone(originalResponse);
|
|
103
|
+
const errors = [];
|
|
104
|
+
let referenceCreated = false;
|
|
105
|
+
let totalReferenceSize = 0;
|
|
106
|
+
for (const contentInfo of analysis.contents) {
|
|
107
|
+
if (this.contentStorage.shouldUseReference(
|
|
108
|
+
typeof contentInfo.content === "string" ? contentInfo.content : JSON.stringify(contentInfo.content)
|
|
109
|
+
)) {
|
|
110
|
+
try {
|
|
111
|
+
const contentBuffer = Buffer.from(
|
|
112
|
+
typeof contentInfo.content === "string" ? contentInfo.content : JSON.stringify(contentInfo.content),
|
|
113
|
+
"utf8"
|
|
114
|
+
);
|
|
115
|
+
const contentType = this.mapMimeTypeToContentType(contentInfo.mimeType);
|
|
116
|
+
const metadata = {
|
|
117
|
+
contentType,
|
|
118
|
+
source: "mcp_tool",
|
|
119
|
+
mcpToolName: `${serverName}::${toolName}`,
|
|
120
|
+
tags: ["mcp_response", serverName, toolName]
|
|
121
|
+
};
|
|
122
|
+
if (contentInfo.mimeType !== void 0) {
|
|
123
|
+
metadata.mimeType = contentInfo.mimeType;
|
|
124
|
+
}
|
|
125
|
+
const reference = await this.contentStorage.storeContentIfLarge(
|
|
126
|
+
contentBuffer,
|
|
127
|
+
metadata
|
|
128
|
+
);
|
|
129
|
+
if (reference) {
|
|
130
|
+
this.replaceContentInResponse(
|
|
131
|
+
processedResponse,
|
|
132
|
+
contentInfo.content,
|
|
133
|
+
this.createLightweightReference(reference)
|
|
134
|
+
);
|
|
135
|
+
referenceCreated = true;
|
|
136
|
+
totalReferenceSize += contentBuffer.length;
|
|
137
|
+
}
|
|
138
|
+
} catch (error) {
|
|
139
|
+
errors.push(`Failed to create reference: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const result = {
|
|
144
|
+
content: processedResponse,
|
|
145
|
+
wasProcessed: true,
|
|
146
|
+
referenceCreated,
|
|
147
|
+
originalSize: totalReferenceSize
|
|
148
|
+
};
|
|
149
|
+
if (errors.length > 0) {
|
|
150
|
+
result.errors = errors;
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
createLightweightReference(reference) {
|
|
155
|
+
return {
|
|
156
|
+
type: "content_reference",
|
|
157
|
+
referenceId: reference.referenceId,
|
|
158
|
+
preview: reference.preview,
|
|
159
|
+
size: reference.metadata.sizeBytes,
|
|
160
|
+
contentType: reference.metadata.contentType,
|
|
161
|
+
format: "ref://{id}",
|
|
162
|
+
_isReference: true
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
replaceContentInResponse(obj, oldContent, newContent) {
|
|
166
|
+
if (obj === null || obj === void 0) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (Array.isArray(obj)) {
|
|
170
|
+
for (let i = 0; i < obj.length; i++) {
|
|
171
|
+
if (obj[i] === oldContent) {
|
|
172
|
+
obj[i] = newContent;
|
|
173
|
+
} else {
|
|
174
|
+
this.replaceContentInResponse(obj[i], oldContent, newContent);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (typeof obj === "object") {
|
|
180
|
+
const record = obj;
|
|
181
|
+
if (record.type === "text" && record.text === oldContent) {
|
|
182
|
+
for (const key of Object.keys(record)) {
|
|
183
|
+
delete record[key];
|
|
184
|
+
}
|
|
185
|
+
for (const key of Object.keys(newContent)) {
|
|
186
|
+
record[key] = newContent[key];
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
for (const key in record) {
|
|
191
|
+
if (record[key] === oldContent) {
|
|
192
|
+
record[key] = newContent;
|
|
193
|
+
} else {
|
|
194
|
+
this.replaceContentInResponse(record[key], oldContent, newContent);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
detectMimeType(content) {
|
|
200
|
+
if (content.trim().startsWith("{") || content.trim().startsWith("[")) {
|
|
201
|
+
return "application/json";
|
|
202
|
+
}
|
|
203
|
+
if (content.includes("<html>") || content.includes("<!DOCTYPE")) {
|
|
204
|
+
return "text/html";
|
|
205
|
+
}
|
|
206
|
+
if (content.includes("# ") || content.includes("## ")) {
|
|
207
|
+
return "text/markdown";
|
|
208
|
+
}
|
|
209
|
+
return "text/plain";
|
|
210
|
+
}
|
|
211
|
+
mapMimeTypeToContentType(mimeType) {
|
|
212
|
+
if (!mimeType) return "text";
|
|
213
|
+
if (mimeType.startsWith("text/plain")) return "text";
|
|
214
|
+
if (mimeType === "application/json") return "json";
|
|
215
|
+
if (mimeType === "text/html") return "html";
|
|
216
|
+
if (mimeType === "text/markdown") return "markdown";
|
|
217
|
+
if (mimeType.startsWith("text/")) return "text";
|
|
218
|
+
return "binary";
|
|
219
|
+
}
|
|
220
|
+
deepClone(obj) {
|
|
221
|
+
if (obj === null || typeof obj !== "object") {
|
|
222
|
+
return obj;
|
|
223
|
+
}
|
|
224
|
+
if (obj instanceof Date) {
|
|
225
|
+
return new Date(obj.getTime());
|
|
226
|
+
}
|
|
227
|
+
if (Array.isArray(obj)) {
|
|
228
|
+
return obj.map((item) => this.deepClone(item));
|
|
229
|
+
}
|
|
230
|
+
const cloned = {};
|
|
231
|
+
for (const key in obj) {
|
|
232
|
+
if (obj.hasOwnProperty(key)) {
|
|
233
|
+
cloned[key] = this.deepClone(obj[key]);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return cloned;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
export {
|
|
240
|
+
MCPContentProcessor
|
|
241
|
+
};
|
|
242
|
+
//# sourceMappingURL=index27.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index27.js","sources":["../../src/mcp/ContentProcessor.ts"],"sourcesContent":["import type { ContentType, ContentSource } from '../types/content-reference';\nimport type { ContentStorage } from '../memory/ContentStorage';\nimport { Logger } from '@hashgraphonline/standards-sdk';\n\nexport interface MCPResponseContent {\n content: unknown;\n type: 'text' | 'image' | 'resource' | 'text[]' | 'image[]';\n sizeBytes: number;\n mimeType?: string;\n}\n\nexport interface ProcessedResponse {\n content: unknown;\n wasProcessed: boolean;\n referenceCreated?: boolean;\n referenceId?: string;\n originalSize?: number;\n errors?: string[];\n}\n\nexport interface ContentAnalysis {\n shouldProcess: boolean;\n contents: MCPResponseContent[];\n totalSize: number;\n largestContentSize: number;\n}\n\nexport class MCPContentProcessor {\n private contentStorage: ContentStorage;\n private logger: Logger;\n\n constructor(contentStorage: ContentStorage, logger: Logger) {\n this.contentStorage = contentStorage;\n this.logger = logger;\n }\n\n analyzeResponse(response: unknown): ContentAnalysis {\n const contents: MCPResponseContent[] = [];\n let totalSize = 0;\n\n this.extractContentFromResponse(response, contents);\n\n totalSize = contents.reduce((sum, content) => sum + content.sizeBytes, 0);\n const largestContentSize = contents.reduce((max, content) => \n Math.max(max, content.sizeBytes), 0);\n\n const shouldProcess = contents.some(content => \n this.contentStorage.shouldUseReference(\n typeof content.content === 'string' \n ? content.content \n : JSON.stringify(content.content)\n )\n );\n\n return {\n shouldProcess,\n contents,\n totalSize,\n largestContentSize\n };\n }\n\n async processResponse(\n response: unknown,\n serverName: string,\n toolName: string\n ): Promise<ProcessedResponse> {\n try {\n const analysis = this.analyzeResponse(response);\n \n if (!analysis.shouldProcess) {\n return {\n content: response,\n wasProcessed: false\n };\n }\n\n const processedResponse = await this.createReferencedResponse(\n response,\n analysis,\n serverName,\n toolName\n );\n\n return processedResponse;\n } catch (error) {\n this.logger.error('Error processing MCP response:', error);\n return {\n content: response,\n wasProcessed: false,\n errors: [error instanceof Error ? error.message : 'Unknown processing error']\n };\n }\n }\n\n private extractContentFromResponse(obj: unknown, contents: MCPResponseContent[]): void {\n if (obj === null || obj === undefined) {\n return;\n }\n\n if (Array.isArray(obj)) {\n obj.forEach(item => this.extractContentFromResponse(item, contents));\n return;\n }\n\n if (typeof obj === 'object') {\n const record = obj as Record<string, unknown>;\n \n if (record.type === 'text' && typeof record.text === 'string') {\n contents.push({\n content: record.text,\n type: 'text',\n sizeBytes: Buffer.byteLength(record.text, 'utf8'),\n mimeType: this.detectMimeType(record.text as string)\n });\n return;\n }\n\n if (record.type === 'image' && typeof record.data === 'string') {\n contents.push({\n content: record.data,\n type: 'image',\n sizeBytes: Math.ceil(record.data.length * 0.75),\n mimeType: record.mimeType as string || 'image/jpeg'\n });\n return;\n }\n\n if (record.type === 'resource' && record.resource) {\n const resourceStr = JSON.stringify(record.resource);\n contents.push({\n content: resourceStr,\n type: 'resource',\n sizeBytes: Buffer.byteLength(resourceStr, 'utf8'),\n mimeType: 'application/json'\n });\n return;\n }\n\n Object.values(record).forEach(value => \n this.extractContentFromResponse(value, contents));\n return;\n }\n\n if (typeof obj === 'string') {\n if (obj.length > 1000) {\n contents.push({\n content: obj,\n type: 'text',\n sizeBytes: Buffer.byteLength(obj, 'utf8'),\n mimeType: this.detectMimeType(obj)\n });\n }\n }\n }\n\n private async createReferencedResponse(\n originalResponse: unknown,\n analysis: ContentAnalysis,\n serverName: string,\n toolName: string\n ): Promise<ProcessedResponse> {\n const processedResponse = this.deepClone(originalResponse);\n const errors: string[] = [];\n let referenceCreated = false;\n let totalReferenceSize = 0;\n\n for (const contentInfo of analysis.contents) {\n if (this.contentStorage.shouldUseReference(\n typeof contentInfo.content === 'string' \n ? contentInfo.content \n : JSON.stringify(contentInfo.content)\n )) {\n try {\n const contentBuffer = Buffer.from(\n typeof contentInfo.content === 'string' \n ? contentInfo.content \n : JSON.stringify(contentInfo.content),\n 'utf8'\n );\n\n const contentType = this.mapMimeTypeToContentType(contentInfo.mimeType);\n \n const metadata: Parameters<typeof this.contentStorage.storeContentIfLarge>[1] = {\n contentType,\n source: 'mcp_tool' as ContentSource,\n mcpToolName: `${serverName}::${toolName}`,\n tags: ['mcp_response', serverName, toolName]\n };\n \n if (contentInfo.mimeType !== undefined) {\n metadata.mimeType = contentInfo.mimeType;\n }\n \n const reference = await this.contentStorage.storeContentIfLarge(\n contentBuffer,\n metadata\n );\n\n if (reference) {\n this.replaceContentInResponse(\n processedResponse,\n contentInfo.content,\n this.createLightweightReference(reference)\n );\n referenceCreated = true;\n totalReferenceSize += contentBuffer.length;\n }\n } catch (error) {\n errors.push(`Failed to create reference: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n }\n\n const result: ProcessedResponse = {\n content: processedResponse,\n wasProcessed: true,\n referenceCreated,\n originalSize: totalReferenceSize\n };\n \n if (errors.length > 0) {\n result.errors = errors;\n }\n \n return result;\n }\n\n private createLightweightReference(reference: any): Record<string, unknown> {\n return {\n type: 'content_reference',\n referenceId: reference.referenceId,\n preview: reference.preview,\n size: reference.metadata.sizeBytes,\n contentType: reference.metadata.contentType,\n format: 'ref://{id}',\n _isReference: true\n };\n }\n\n private replaceContentInResponse(obj: unknown, oldContent: unknown, newContent: any): void {\n if (obj === null || obj === undefined) {\n return;\n }\n\n if (Array.isArray(obj)) {\n for (let i = 0; i < obj.length; i++) {\n if (obj[i] === oldContent) {\n obj[i] = newContent;\n } else {\n this.replaceContentInResponse(obj[i], oldContent, newContent);\n }\n }\n return;\n }\n\n if (typeof obj === 'object') {\n const record = obj as Record<string, unknown>;\n if (record.type === 'text' && record.text === oldContent) {\n for (const key of Object.keys(record)) {\n delete record[key];\n }\n for (const key of Object.keys(newContent)) {\n record[key] = newContent[key];\n }\n return;\n }\n for (const key in record) {\n if (record[key] === oldContent) {\n record[key] = newContent;\n } else {\n this.replaceContentInResponse(record[key], oldContent, newContent);\n }\n }\n }\n }\n\n private detectMimeType(content: string): string {\n if (content.trim().startsWith('{') || content.trim().startsWith('[')) {\n return 'application/json';\n }\n if (content.includes('<html>') || content.includes('<!DOCTYPE')) {\n return 'text/html';\n }\n if (content.includes('# ') || content.includes('## ')) {\n return 'text/markdown';\n }\n return 'text/plain';\n }\n\n private mapMimeTypeToContentType(mimeType?: string): ContentType {\n if (!mimeType) return 'text';\n \n if (mimeType.startsWith('text/plain')) return 'text';\n if (mimeType === 'application/json') return 'json';\n if (mimeType === 'text/html') return 'html';\n if (mimeType === 'text/markdown') return 'markdown';\n if (mimeType.startsWith('text/')) return 'text';\n \n return 'binary';\n }\n\n private deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n \n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n \n if (Array.isArray(obj)) {\n return obj.map(item => this.deepClone(item)) as T;\n }\n \n const cloned = {} as T;\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n cloned[key] = this.deepClone(obj[key]);\n }\n }\n \n return cloned;\n }\n}"],"names":[],"mappings":"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"}
|
package/dist/esm/index5.js
CHANGED
|
@@ -1,35 +1,32 @@
|
|
|
1
|
-
import { BasePlugin } from "hedera-agent-kit";
|
|
2
|
-
import { TransferHbarTool } from "./
|
|
3
|
-
|
|
1
|
+
import { BasePlugin, HederaAirdropTokenTool } from "hedera-agent-kit";
|
|
2
|
+
import { TransferHbarTool } from "./index18.js";
|
|
3
|
+
import { AirdropToolWrapper } from "./index19.js";
|
|
4
|
+
class HbarPlugin extends BasePlugin {
|
|
4
5
|
constructor() {
|
|
5
6
|
super(...arguments);
|
|
6
|
-
this.id = "hbar
|
|
7
|
-
this.name = "HBAR
|
|
8
|
-
this.description = "HBAR transfer tool with
|
|
7
|
+
this.id = "hbar";
|
|
8
|
+
this.name = "HBAR Plugin";
|
|
9
|
+
this.description = "HBAR operations: transfer tool with robust decimal handling and compatibility with airdrop improvements";
|
|
9
10
|
this.version = "1.0.0";
|
|
10
11
|
this.author = "Hashgraph Online";
|
|
11
12
|
this.namespace = "account";
|
|
12
13
|
this.tools = [];
|
|
14
|
+
this.originalAirdropTool = null;
|
|
13
15
|
}
|
|
14
16
|
async initialize(context) {
|
|
15
17
|
await super.initialize(context);
|
|
16
18
|
const hederaKit = context.config.hederaKit;
|
|
17
19
|
if (!hederaKit) {
|
|
18
20
|
this.context.logger.warn(
|
|
19
|
-
"HederaKit not found in context. HBAR
|
|
21
|
+
"HederaKit not found in context. HBAR tools will not be available."
|
|
20
22
|
);
|
|
21
23
|
return;
|
|
22
24
|
}
|
|
23
25
|
try {
|
|
24
26
|
this.initializeTools();
|
|
25
|
-
this.context.logger.info(
|
|
26
|
-
"HBAR Transfer Plugin initialized successfully"
|
|
27
|
-
);
|
|
27
|
+
this.context.logger.info("HBAR Plugin initialized successfully");
|
|
28
28
|
} catch (error) {
|
|
29
|
-
this.context.logger.error(
|
|
30
|
-
"Failed to initialize HBAR Transfer plugin:",
|
|
31
|
-
error
|
|
32
|
-
);
|
|
29
|
+
this.context.logger.error("Failed to initialize HBAR plugin:", error);
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
32
|
initializeTools() {
|
|
@@ -37,12 +34,28 @@ class HbarTransferPlugin extends BasePlugin {
|
|
|
37
34
|
if (!hederaKit) {
|
|
38
35
|
throw new Error("HederaKit not found in context config");
|
|
39
36
|
}
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const transfer = new TransferHbarTool({
|
|
38
|
+
hederaKit,
|
|
39
|
+
logger: this.context.logger
|
|
40
|
+
});
|
|
41
|
+
this.tools = [transfer];
|
|
42
|
+
try {
|
|
43
|
+
this.context.logger.info(
|
|
44
|
+
"Creating wrapper for passed original airdrop tool"
|
|
45
|
+
);
|
|
46
|
+
const airdropTool = new HederaAirdropTokenTool({
|
|
42
47
|
hederaKit,
|
|
43
48
|
logger: this.context.logger
|
|
44
|
-
})
|
|
45
|
-
|
|
49
|
+
});
|
|
50
|
+
const wrappedAirdropTool = new AirdropToolWrapper(airdropTool, hederaKit);
|
|
51
|
+
this.tools.push(wrappedAirdropTool);
|
|
52
|
+
this.context.logger.info("Added wrapped airdrop tool to HBAR Plugin");
|
|
53
|
+
} catch (error) {
|
|
54
|
+
this.context.logger.error("Error creating airdrop tool wrapper:", error);
|
|
55
|
+
}
|
|
56
|
+
this.context.logger.info(
|
|
57
|
+
`HBAR Plugin tools initialized with ${this.tools.length} tools`
|
|
58
|
+
);
|
|
46
59
|
}
|
|
47
60
|
getTools() {
|
|
48
61
|
return this.tools;
|
|
@@ -52,6 +65,6 @@ class HbarTransferPlugin extends BasePlugin {
|
|
|
52
65
|
}
|
|
53
66
|
}
|
|
54
67
|
export {
|
|
55
|
-
|
|
68
|
+
HbarPlugin
|
|
56
69
|
};
|
|
57
70
|
//# sourceMappingURL=index5.js.map
|
package/dist/esm/index5.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index5.js","sources":["../../src/plugins/hbar
|
|
1
|
+
{"version":3,"file":"index5.js","sources":["../../src/plugins/hbar/HbarPlugin.ts"],"sourcesContent":["import {\n GenericPluginContext,\n HederaTool,\n BasePlugin,\n HederaAgentKit,\n HederaAirdropTokenTool,\n} from 'hedera-agent-kit';\nimport { TransferHbarTool } from './TransferHbarTool';\nimport { AirdropToolWrapper } from './AirdropToolWrapper';\nimport { StructuredTool } from '@langchain/core/tools';\n\nexport class HbarPlugin extends BasePlugin {\n id = 'hbar';\n name = 'HBAR Plugin';\n description =\n 'HBAR operations: transfer tool with robust decimal handling and compatibility with airdrop improvements';\n version = '1.0.0';\n author = 'Hashgraph Online';\n namespace = 'account';\n\n private tools: (HederaTool | AirdropToolWrapper)[] = [];\n private originalAirdropTool: StructuredTool | null = null;\n\n override async initialize(context: GenericPluginContext): Promise<void> {\n await super.initialize(context);\n\n const hederaKit = context.config.hederaKit as HederaAgentKit;\n if (!hederaKit) {\n this.context.logger.warn(\n 'HederaKit not found in context. HBAR tools will not be available.'\n );\n return;\n }\n\n try {\n this.initializeTools();\n\n this.context.logger.info('HBAR Plugin initialized successfully');\n } catch (error) {\n this.context.logger.error('Failed to initialize HBAR plugin:', error);\n }\n }\n\n private initializeTools(): void {\n const hederaKit = this.context.config.hederaKit as HederaAgentKit;\n if (!hederaKit) {\n throw new Error('HederaKit not found in context config');\n }\n\n const transfer = new TransferHbarTool({\n hederaKit: hederaKit,\n logger: this.context.logger,\n });\n\n this.tools = [transfer];\n\n try {\n this.context.logger.info(\n 'Creating wrapper for passed original airdrop tool'\n );\n\n const airdropTool = new HederaAirdropTokenTool({\n hederaKit: hederaKit,\n logger: this.context.logger,\n });\n const wrappedAirdropTool = new AirdropToolWrapper(airdropTool, hederaKit);\n this.tools.push(wrappedAirdropTool);\n this.context.logger.info('Added wrapped airdrop tool to HBAR Plugin');\n } catch (error) {\n this.context.logger.error('Error creating airdrop tool wrapper:', error);\n }\n\n this.context.logger.info(\n `HBAR Plugin tools initialized with ${this.tools.length} tools`\n );\n }\n\n override getTools(): HederaTool[] {\n // @ts-ignore\n return this.tools;\n }\n\n async shutdown(): Promise<void> {\n this.tools = [];\n }\n}\n"],"names":[],"mappings":";;;AAWO,MAAM,mBAAmB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AACL,SAAA,KAAK;AACL,SAAA,OAAO;AACP,SAAA,cACE;AACF,SAAA,UAAU;AACV,SAAA,SAAS;AACT,SAAA,YAAY;AAEZ,SAAQ,QAA6C,CAAA;AACrD,SAAQ,sBAA6C;AAAA,EAAA;AAAA,EAErD,MAAe,WAAW,SAA8C;AACtE,UAAM,MAAM,WAAW,OAAO;AAE9B,UAAM,YAAY,QAAQ,OAAO;AACjC,QAAI,CAAC,WAAW;AACd,WAAK,QAAQ,OAAO;AAAA,QAClB;AAAA,MAAA;AAEF;AAAA,IACF;AAEA,QAAI;AACF,WAAK,gBAAA;AAEL,WAAK,QAAQ,OAAO,KAAK,sCAAsC;AAAA,IACjE,SAAS,OAAO;AACd,WAAK,QAAQ,OAAO,MAAM,qCAAqC,KAAK;AAAA,IACtE;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,YAAY,KAAK,QAAQ,OAAO;AACtC,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAEA,UAAM,WAAW,IAAI,iBAAiB;AAAA,MACpC;AAAA,MACA,QAAQ,KAAK,QAAQ;AAAA,IAAA,CACtB;AAED,SAAK,QAAQ,CAAC,QAAQ;AAEtB,QAAI;AACF,WAAK,QAAQ,OAAO;AAAA,QAClB;AAAA,MAAA;AAGF,YAAM,cAAc,IAAI,uBAAuB;AAAA,QAC7C;AAAA,QACA,QAAQ,KAAK,QAAQ;AAAA,MAAA,CACtB;AACD,YAAM,qBAAqB,IAAI,mBAAmB,aAAa,SAAS;AACxE,WAAK,MAAM,KAAK,kBAAkB;AAClC,WAAK,QAAQ,OAAO,KAAK,2CAA2C;AAAA,IACtE,SAAS,OAAO;AACd,WAAK,QAAQ,OAAO,MAAM,wCAAwC,KAAK;AAAA,IACzE;AAEA,SAAK,QAAQ,OAAO;AAAA,MAClB,sCAAsC,KAAK,MAAM,MAAM;AAAA,IAAA;AAAA,EAE3D;AAAA,EAES,WAAyB;AAEhC,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,WAA0B;AAC9B,SAAK,QAAQ,CAAA;AAAA,EACf;AACF;"}
|