@hashgraphonline/conversational-agent 0.1.215 ā 0.1.217
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/conversational-agent.d.ts +8 -0
- package/dist/cjs/core/ToolRegistry.d.ts +130 -0
- package/dist/cjs/execution/ExecutionPipeline.d.ts +81 -0
- package/dist/cjs/forms/FormEngine.d.ts +121 -0
- package/dist/cjs/forms/form-generator.d.ts +39 -2
- package/dist/cjs/forms/types.d.ts +21 -2
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +3 -4
- package/dist/cjs/langchain/FormAwareAgentExecutor.d.ts +53 -4
- package/dist/cjs/langchain/FormValidatingToolWrapper.d.ts +43 -6
- package/dist/cjs/langchain-agent.d.ts +49 -0
- package/dist/cjs/memory/ContentStorage.d.ts +7 -0
- package/dist/cjs/memory/SmartMemoryManager.d.ts +1 -0
- package/dist/cjs/services/ContentStoreManager.d.ts +11 -1
- package/dist/cjs/utils/ResponseFormatter.d.ts +26 -0
- package/dist/esm/index.js +2 -6
- package/dist/esm/index12.js +1 -1
- package/dist/esm/index12.js.map +1 -1
- package/dist/esm/index14.js +23 -5
- package/dist/esm/index14.js.map +1 -1
- package/dist/esm/index15.js +25 -4
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index16.js +4 -2
- package/dist/esm/index16.js.map +1 -1
- package/dist/esm/index17.js +2 -7
- package/dist/esm/index17.js.map +1 -1
- package/dist/esm/index18.js +292 -150
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index19.js +158 -65
- package/dist/esm/index19.js.map +1 -1
- package/dist/esm/index20.js +94 -270
- package/dist/esm/index20.js.map +1 -1
- package/dist/esm/index21.js +1 -1
- package/dist/esm/index23.js +14 -0
- package/dist/esm/index23.js.map +1 -1
- package/dist/esm/index24.js +508 -12
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index25.js +1 -1
- package/dist/esm/index25.js.map +1 -1
- package/dist/esm/index26.js +1 -1
- package/dist/esm/index26.js.map +1 -1
- package/dist/esm/index27.js +189 -128
- package/dist/esm/index27.js.map +1 -1
- package/dist/esm/index28.js +164 -45
- package/dist/esm/index28.js.map +1 -1
- package/dist/esm/index29.js +302 -24
- package/dist/esm/index29.js.map +1 -1
- package/dist/esm/index30.js +144 -80
- package/dist/esm/index30.js.map +1 -1
- package/dist/esm/index31.js +63 -7
- package/dist/esm/index31.js.map +1 -1
- package/dist/esm/index32.js +24 -236
- package/dist/esm/index32.js.map +1 -1
- package/dist/esm/index33.js +95 -0
- package/dist/esm/index33.js.map +1 -0
- package/dist/esm/index34.js +245 -0
- package/dist/esm/index34.js.map +1 -0
- package/dist/esm/index5.js.map +1 -1
- package/dist/esm/index6.js +61 -22
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index8.js +653 -131
- package/dist/esm/index8.js.map +1 -1
- package/dist/types/conversational-agent.d.ts +8 -0
- package/dist/types/core/ToolRegistry.d.ts +130 -0
- package/dist/types/execution/ExecutionPipeline.d.ts +81 -0
- package/dist/types/forms/FormEngine.d.ts +121 -0
- package/dist/types/forms/form-generator.d.ts +39 -2
- package/dist/types/forms/types.d.ts +21 -2
- package/dist/types/index.d.ts +3 -4
- package/dist/types/langchain/FormAwareAgentExecutor.d.ts +53 -4
- package/dist/types/langchain/FormValidatingToolWrapper.d.ts +43 -6
- package/dist/types/langchain-agent.d.ts +49 -0
- package/dist/types/memory/ContentStorage.d.ts +7 -0
- package/dist/types/memory/SmartMemoryManager.d.ts +1 -0
- package/dist/types/services/ContentStoreManager.d.ts +11 -1
- package/dist/types/utils/ResponseFormatter.d.ts +26 -0
- package/package.json +13 -10
- package/src/config/system-message.ts +14 -0
- package/src/context/ReferenceContextManager.ts +1 -1
- package/src/conversational-agent.ts +91 -36
- package/src/core/ToolRegistry.ts +358 -0
- package/src/execution/ExecutionPipeline.ts +301 -0
- package/src/forms/FormEngine.ts +443 -0
- package/src/forms/field-type-registry.ts +1 -13
- package/src/forms/form-generator.ts +394 -237
- package/src/forms/types.ts +20 -3
- package/src/index.ts +6 -10
- package/src/langchain/FormAwareAgentExecutor.ts +653 -22
- package/src/langchain/FormValidatingToolWrapper.ts +216 -93
- package/src/langchain-agent.ts +924 -185
- package/src/mcp/ContentProcessor.ts +20 -4
- package/src/mcp/MCPClientManager.ts +1 -1
- package/src/mcp/adapters/langchain.ts +1 -1
- package/src/memory/ContentStorage.ts +25 -5
- package/src/memory/SmartMemoryManager.ts +27 -4
- package/src/memory/TokenCounter.ts +1 -1
- package/src/plugins/hbar/HbarPlugin.ts +0 -1
- package/src/scripts/test-external-tool-wrapper.ts +3 -12
- package/src/scripts/test-hedera-kit-wrapper.ts +6 -22
- package/src/scripts/test-inscribe-form-generation.ts +24 -42
- package/src/scripts/test-inscribe-wrapper-verification.ts +1 -7
- package/src/services/ContentStoreManager.ts +23 -9
- package/src/services/EntityResolver.ts +2 -9
- package/src/tools/EntityResolverTool.ts +5 -8
- package/src/utils/ResponseFormatter.ts +146 -0
- package/dist/cjs/examples/external-tool-wrapper-example.d.ts +0 -131
- package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +0 -14
- package/dist/cjs/langchain/external-tool-wrapper.d.ts +0 -179
- package/dist/cjs/scripts/test-external-tool-wrapper.d.ts +0 -5
- package/dist/cjs/scripts/test-hedera-kit-wrapper.d.ts +0 -36
- package/dist/cjs/scripts/test-inscribe-form-generation.d.ts +0 -15
- package/dist/cjs/scripts/test-inscribe-wrapper-verification.d.ts +0 -13
- package/dist/types/examples/external-tool-wrapper-example.d.ts +0 -131
- package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +0 -14
- package/dist/types/langchain/external-tool-wrapper.d.ts +0 -179
- package/dist/types/scripts/test-external-tool-wrapper.d.ts +0 -5
- package/dist/types/scripts/test-hedera-kit-wrapper.d.ts +0 -36
- package/dist/types/scripts/test-inscribe-form-generation.d.ts +0 -15
- package/dist/types/scripts/test-inscribe-wrapper-verification.d.ts +0 -13
- package/src/examples/external-tool-wrapper-example.ts +0 -227
- package/src/langchain/ContentAwareAgentExecutor.ts +0 -19
- package/src/langchain/external-tool-wrapper.ts +0 -486
|
@@ -18,6 +18,19 @@ export interface ProcessedResponse {
|
|
|
18
18
|
errors?: string[];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Content reference interface
|
|
23
|
+
*/
|
|
24
|
+
interface ContentReference {
|
|
25
|
+
referenceId: string;
|
|
26
|
+
preview?: string;
|
|
27
|
+
metadata: {
|
|
28
|
+
sizeBytes: number;
|
|
29
|
+
contentType?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
export interface ContentAnalysis {
|
|
22
35
|
shouldProcess: boolean;
|
|
23
36
|
contents: MCPResponseContent[];
|
|
@@ -226,7 +239,7 @@ export class MCPContentProcessor {
|
|
|
226
239
|
return result;
|
|
227
240
|
}
|
|
228
241
|
|
|
229
|
-
private createLightweightReference(reference:
|
|
242
|
+
private createLightweightReference(reference: ContentReference): Record<string, unknown> {
|
|
230
243
|
return {
|
|
231
244
|
type: 'content_reference',
|
|
232
245
|
referenceId: reference.referenceId,
|
|
@@ -238,7 +251,7 @@ export class MCPContentProcessor {
|
|
|
238
251
|
};
|
|
239
252
|
}
|
|
240
253
|
|
|
241
|
-
private replaceContentInResponse(obj: unknown, oldContent: unknown, newContent:
|
|
254
|
+
private replaceContentInResponse(obj: unknown, oldContent: unknown, newContent: unknown): void {
|
|
242
255
|
if (obj === null || obj === undefined) {
|
|
243
256
|
return;
|
|
244
257
|
}
|
|
@@ -260,8 +273,11 @@ export class MCPContentProcessor {
|
|
|
260
273
|
for (const key of Object.keys(record)) {
|
|
261
274
|
delete record[key];
|
|
262
275
|
}
|
|
263
|
-
|
|
264
|
-
|
|
276
|
+
if (typeof newContent === 'object' && newContent !== null) {
|
|
277
|
+
const newContentRecord = newContent as Record<string, unknown>;
|
|
278
|
+
for (const key of Object.keys(newContentRecord)) {
|
|
279
|
+
record[key] = newContentRecord[key];
|
|
280
|
+
}
|
|
265
281
|
}
|
|
266
282
|
return;
|
|
267
283
|
}
|
|
@@ -3,7 +3,7 @@ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
|
|
|
3
3
|
import type { MCPServerConfig, MCPToolInfo, MCPConnectionStatus } from './types';
|
|
4
4
|
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
5
5
|
import type { ContentStorage } from '../memory/ContentStorage';
|
|
6
|
-
import { MCPContentProcessor
|
|
6
|
+
import { MCPContentProcessor } from './ContentProcessor';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Manages connections to MCP servers and tool discovery
|
|
@@ -207,7 +207,7 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
207
207
|
matches = this.messages
|
|
208
208
|
.filter(stored => regex.test(stored.message.content as string))
|
|
209
209
|
.map(stored => stored.message);
|
|
210
|
-
} catch
|
|
210
|
+
} catch {
|
|
211
211
|
return [];
|
|
212
212
|
}
|
|
213
213
|
} else {
|
|
@@ -365,7 +365,6 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
365
365
|
}));
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
|
|
369
368
|
/**
|
|
370
369
|
* Determine if content should be stored as a reference based on size
|
|
371
370
|
*/
|
|
@@ -377,6 +376,9 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
377
376
|
/**
|
|
378
377
|
* Store content and return a reference if it exceeds the size threshold
|
|
379
378
|
* Otherwise returns null to indicate direct content should be used
|
|
379
|
+
*
|
|
380
|
+
* Special case: Image files are ALWAYS stored as references regardless of size
|
|
381
|
+
* because they need special handling for inscription tools
|
|
380
382
|
*/
|
|
381
383
|
async storeContentIfLarge(
|
|
382
384
|
content: Buffer | string,
|
|
@@ -392,7 +394,9 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
392
394
|
): Promise<ContentReference | null> {
|
|
393
395
|
const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content, 'utf8');
|
|
394
396
|
|
|
395
|
-
|
|
397
|
+
const isImageFile = this.isImageContent(metadata.mimeType, metadata.fileName);
|
|
398
|
+
|
|
399
|
+
if (!isImageFile && !this.shouldUseReference(buffer)) {
|
|
396
400
|
return null;
|
|
397
401
|
}
|
|
398
402
|
|
|
@@ -744,7 +748,6 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
744
748
|
return { ...this.referenceConfig };
|
|
745
749
|
}
|
|
746
750
|
|
|
747
|
-
|
|
748
751
|
private async enforceReferenceStorageLimits(): Promise<void> {
|
|
749
752
|
if (this.contentStore.size >= this.referenceConfig.maxReferences) {
|
|
750
753
|
await this.performCleanup();
|
|
@@ -845,6 +848,23 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
845
848
|
}
|
|
846
849
|
}
|
|
847
850
|
|
|
851
|
+
/**
|
|
852
|
+
* Check if content is an image file based on MIME type or filename
|
|
853
|
+
*/
|
|
854
|
+
private isImageContent(mimeType?: string, fileName?: string): boolean {
|
|
855
|
+
if (mimeType && mimeType.startsWith('image/')) {
|
|
856
|
+
return true;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
if (fileName) {
|
|
860
|
+
const lowerFileName = fileName.toLowerCase();
|
|
861
|
+
const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.svg', '.tiff', '.ico'];
|
|
862
|
+
return imageExtensions.some(ext => lowerFileName.endsWith(ext));
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
return false;
|
|
866
|
+
}
|
|
867
|
+
|
|
848
868
|
private recordPerformanceMetric(type: 'creation' | 'resolution' | 'cleanup', timeMs: number): void {
|
|
849
869
|
const metrics = this.referenceStats.performanceMetrics;
|
|
850
870
|
const maxRecords = 100;
|
|
@@ -880,7 +900,7 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
880
900
|
this.cleanupTimer = setInterval(async () => {
|
|
881
901
|
try {
|
|
882
902
|
await this.performCleanup();
|
|
883
|
-
} catch
|
|
903
|
+
} catch {
|
|
884
904
|
}
|
|
885
905
|
}, this.referenceConfig.cleanupIntervalMs);
|
|
886
906
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseMessage } from '@langchain/core/messages';
|
|
2
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
2
3
|
import { MemoryWindow } from './MemoryWindow';
|
|
3
4
|
import { ContentStorage } from './ContentStorage';
|
|
4
5
|
import { TokenCounter } from './TokenCounter';
|
|
@@ -88,6 +89,7 @@ export class SmartMemoryManager {
|
|
|
88
89
|
private _contentStorage: ContentStorage;
|
|
89
90
|
private tokenCounter: TokenCounter;
|
|
90
91
|
private config: Required<SmartMemoryConfig>;
|
|
92
|
+
private logger: Logger;
|
|
91
93
|
|
|
92
94
|
private static readonly DEFAULT_CONFIG: Required<SmartMemoryConfig> = {
|
|
93
95
|
maxTokens: 8000,
|
|
@@ -98,6 +100,7 @@ export class SmartMemoryManager {
|
|
|
98
100
|
|
|
99
101
|
constructor(config: SmartMemoryConfig = {}) {
|
|
100
102
|
this.config = { ...SmartMemoryManager.DEFAULT_CONFIG, ...config };
|
|
103
|
+
this.logger = new Logger({ module: 'SmartMemoryManager' });
|
|
101
104
|
|
|
102
105
|
this.tokenCounter = new TokenCounter(this.config.modelName);
|
|
103
106
|
this._contentStorage = new ContentStorage(this.config.storageLimit);
|
|
@@ -446,7 +449,14 @@ export class SmartMemoryManager {
|
|
|
446
449
|
};
|
|
447
450
|
|
|
448
451
|
this._contentStorage.storeMessages([entityMessage as BaseMessage]);
|
|
449
|
-
} catch (
|
|
452
|
+
} catch (error) {
|
|
453
|
+
this.logger.error('Failed to store entity association', {
|
|
454
|
+
entityId,
|
|
455
|
+
entityName,
|
|
456
|
+
entityType,
|
|
457
|
+
error: error instanceof Error ? error.message : String(error)
|
|
458
|
+
});
|
|
459
|
+
}
|
|
450
460
|
}
|
|
451
461
|
|
|
452
462
|
/**
|
|
@@ -563,7 +573,12 @@ export class SmartMemoryManager {
|
|
|
563
573
|
const results = uniqueAssociations.slice(0, safeLimit);
|
|
564
574
|
|
|
565
575
|
return results;
|
|
566
|
-
} catch (
|
|
576
|
+
} catch (error) {
|
|
577
|
+
this.logger.error('Failed to resolve entity reference', {
|
|
578
|
+
query,
|
|
579
|
+
options,
|
|
580
|
+
error: error instanceof Error ? error.message : String(error)
|
|
581
|
+
});
|
|
567
582
|
return [];
|
|
568
583
|
}
|
|
569
584
|
}
|
|
@@ -616,7 +631,11 @@ export class SmartMemoryManager {
|
|
|
616
631
|
associations.push(parsed as EntityAssociation);
|
|
617
632
|
}
|
|
618
633
|
}
|
|
619
|
-
} catch (
|
|
634
|
+
} catch (parseError) {
|
|
635
|
+
this.logger.warn('Failed to parse entity association from message', {
|
|
636
|
+
messageContent: typeof message.content === 'string' ? message.content.substring(0, 100) : 'non-string',
|
|
637
|
+
error: parseError instanceof Error ? parseError.message : String(parseError)
|
|
638
|
+
});
|
|
620
639
|
continue;
|
|
621
640
|
}
|
|
622
641
|
}
|
|
@@ -635,7 +654,11 @@ export class SmartMemoryManager {
|
|
|
635
654
|
});
|
|
636
655
|
|
|
637
656
|
return results;
|
|
638
|
-
} catch (
|
|
657
|
+
} catch (error) {
|
|
658
|
+
this.logger.error('Failed to get entity associations', {
|
|
659
|
+
entityType,
|
|
660
|
+
error: error instanceof Error ? error.message : String(error)
|
|
661
|
+
});
|
|
639
662
|
return [];
|
|
640
663
|
}
|
|
641
664
|
}
|
|
@@ -9,14 +9,13 @@ async function testExternalToolWrapper() {
|
|
|
9
9
|
console.log('š§Ŗ Testing External Tool Wrapper\n');
|
|
10
10
|
|
|
11
11
|
try {
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
console.log('š Test 1: Basic external tool wrapping');
|
|
14
14
|
const basicTool = examples.basicWrapping();
|
|
15
15
|
console.log(`ā
Tool "${basicTool.name}" wrapped successfully`);
|
|
16
16
|
console.log(` Description: ${basicTool.description}`);
|
|
17
17
|
console.log(` Schema type: ${basicTool.schema.constructor.name}`);
|
|
18
18
|
|
|
19
|
-
// Test the wrapped tool execution
|
|
20
19
|
const testInput = {
|
|
21
20
|
fromAccountId: '0.0.123',
|
|
22
21
|
toAccountId: '0.0.456',
|
|
@@ -27,13 +26,11 @@ async function testExternalToolWrapper() {
|
|
|
27
26
|
const result = await (basicTool as any)._call(testInput);
|
|
28
27
|
console.log(` Execution result: ${result}\n`);
|
|
29
28
|
|
|
30
|
-
// Test 2: Preset configurations
|
|
31
29
|
console.log('š Test 2: Preset configurations');
|
|
32
30
|
const presetTool = examples.presetConfigurations();
|
|
33
31
|
console.log(`ā
Tool "${presetTool.name}" wrapped with preset config`);
|
|
34
32
|
console.log(` Description: ${presetTool.description}\n`);
|
|
35
33
|
|
|
36
|
-
// Test 3: Batch wrapping
|
|
37
34
|
console.log('š Test 3: Batch wrapping multiple tools');
|
|
38
35
|
const batchTools = examples.batchWrapping();
|
|
39
36
|
console.log(`ā
Wrapped ${batchTools.length} tools in batch`);
|
|
@@ -42,16 +39,14 @@ async function testExternalToolWrapper() {
|
|
|
42
39
|
});
|
|
43
40
|
console.log();
|
|
44
41
|
|
|
45
|
-
// Test 4: Form validation integration
|
|
46
42
|
console.log('š Test 4: Form validation integration');
|
|
47
43
|
const formTool = examples.formValidationIntegration();
|
|
48
44
|
console.log(`ā
Tool "${formTool.name}" wrapped with form validation`);
|
|
49
45
|
console.log(` Tool type: ${formTool.constructor.name}`);
|
|
50
46
|
|
|
51
|
-
// Test with incomplete input to trigger form generation
|
|
52
47
|
const incompleteInput = {
|
|
53
48
|
fromAccountId: '0.0.123'
|
|
54
|
-
|
|
49
|
+
|
|
55
50
|
} as any;
|
|
56
51
|
|
|
57
52
|
try {
|
|
@@ -68,17 +63,15 @@ async function testExternalToolWrapper() {
|
|
|
68
63
|
}
|
|
69
64
|
console.log();
|
|
70
65
|
|
|
71
|
-
// Test 5: Custom field configurations
|
|
72
66
|
console.log('š Test 5: Custom field configurations');
|
|
73
67
|
const customTool = examples.customFieldConfigs();
|
|
74
68
|
console.log(`ā
Tool "${customTool.name}" wrapped with custom configs`);
|
|
75
69
|
console.log(` Description: ${customTool.description}`);
|
|
76
70
|
|
|
77
|
-
// Check if schema has render configs attached
|
|
78
71
|
const schema = customTool.schema as any;
|
|
79
72
|
const shape = schema._def.shape();
|
|
80
73
|
let fieldConfigCount = 0;
|
|
81
|
-
for (const [
|
|
74
|
+
for (const [, fieldSchema] of Object.entries(shape)) {
|
|
82
75
|
if ((fieldSchema as any)._renderConfig) {
|
|
83
76
|
fieldConfigCount++;
|
|
84
77
|
}
|
|
@@ -86,7 +79,6 @@ async function testExternalToolWrapper() {
|
|
|
86
79
|
console.log(` Fields with render configs: ${fieldConfigCount}`);
|
|
87
80
|
console.log();
|
|
88
81
|
|
|
89
|
-
// Test 6: Render config helpers
|
|
90
82
|
console.log('š Test 6: Render config helpers');
|
|
91
83
|
const { renderConfigs } = await import('../langchain/external-tool-wrapper');
|
|
92
84
|
|
|
@@ -108,5 +100,4 @@ async function testExternalToolWrapper() {
|
|
|
108
100
|
}
|
|
109
101
|
}
|
|
110
102
|
|
|
111
|
-
// Run the tests
|
|
112
103
|
testExternalToolWrapper().catch(console.error);
|
|
@@ -27,7 +27,7 @@ class MockHederaGetAccountInfoTool extends StructuredTool {
|
|
|
27
27
|
protected async _call(
|
|
28
28
|
input: z.infer<typeof this.schema>
|
|
29
29
|
): Promise<string> {
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
return JSON.stringify({
|
|
32
32
|
success: true,
|
|
33
33
|
accountId: input.accountId,
|
|
@@ -104,13 +104,11 @@ async function testHederaKitWrapper(): Promise<void> {
|
|
|
104
104
|
try {
|
|
105
105
|
logger.info('š Starting Hedera Agent Kit external tool wrapper test');
|
|
106
106
|
|
|
107
|
-
// Create mock tools that simulate hedera-agent-kit tool structure
|
|
108
107
|
const originalTool = new MockHederaGetAccountInfoTool();
|
|
109
108
|
const transferTool = new MockHederaTransferHbarTool();
|
|
110
109
|
logger.info(`š Testing with tool: ${originalTool.name}`);
|
|
111
110
|
logger.info(`š Original tool description: ${originalTool.description}`);
|
|
112
111
|
|
|
113
|
-
// Test 1: Basic external tool wrapping with render configs
|
|
114
112
|
logger.info('\nš§ Test 1: Wrapping external tool with render configs');
|
|
115
113
|
|
|
116
114
|
const wrappedTool = wrapExternalToolWithRenderConfig(originalTool, {
|
|
@@ -129,12 +127,10 @@ async function testHederaKitWrapper(): Promise<void> {
|
|
|
129
127
|
logger.info(`ā
Wrapped tool description: ${wrappedTool.description}`);
|
|
130
128
|
logger.info(`ā
Wrapped tool type: ${wrappedTool.constructor.name}`);
|
|
131
129
|
|
|
132
|
-
// Verify the wrapped tool has enhanced schema
|
|
133
130
|
const enhancedSchema = wrappedTool.schema;
|
|
134
131
|
const hasRenderConfig = !!((enhancedSchema as unknown as { _renderConfig?: unknown })._renderConfig);
|
|
135
132
|
logger.info(`ā
Has tool-level render config: ${hasRenderConfig}`);
|
|
136
133
|
|
|
137
|
-
// Test 2: Integration with FormValidatingToolWrapper
|
|
138
134
|
logger.info('\nš§ Test 2: Integration with FormValidatingToolWrapper');
|
|
139
135
|
|
|
140
136
|
const formGenerator = new FormGenerator();
|
|
@@ -150,16 +146,15 @@ async function testHederaKitWrapper(): Promise<void> {
|
|
|
150
146
|
logger.info(`ā
Form validating tool created: ${formValidatingTool.name}`);
|
|
151
147
|
logger.info(`ā
Form validating tool type: ${formValidatingTool.constructor.name}`);
|
|
152
148
|
|
|
153
|
-
// Test 3: Form generation with missing fields
|
|
154
149
|
logger.info('\nš§ Test 3: Testing form generation with incomplete input');
|
|
155
150
|
|
|
156
151
|
const incompleteInput = {
|
|
157
|
-
|
|
152
|
+
|
|
158
153
|
includeBalances: true
|
|
159
154
|
};
|
|
160
155
|
|
|
161
156
|
try {
|
|
162
|
-
const result = await formValidatingTool._call(incompleteInput as z.infer<typeof originalTool.schema>);
|
|
157
|
+
const result = await (formValidatingTool as any)._call(incompleteInput as z.infer<typeof originalTool.schema>);
|
|
163
158
|
const parsedResult = JSON.parse(result);
|
|
164
159
|
|
|
165
160
|
if (parsedResult.requiresForm) {
|
|
@@ -174,7 +169,6 @@ async function testHederaKitWrapper(): Promise<void> {
|
|
|
174
169
|
logger.error('ā Form generation test failed:', error);
|
|
175
170
|
}
|
|
176
171
|
|
|
177
|
-
// Test 4: Batch wrapping with predefined configs
|
|
178
172
|
logger.info('\nš§ Test 4: Testing batch wrapping with predefined configs');
|
|
179
173
|
|
|
180
174
|
const batchWrappedTools = [
|
|
@@ -187,10 +181,8 @@ async function testHederaKitWrapper(): Promise<void> {
|
|
|
187
181
|
logger.info(`ā
Batch wrapped ${batchWrappedTools.length} tools`);
|
|
188
182
|
logger.info(`ā
Batch wrapped tool: ${batchWrappedTools[0].name}`);
|
|
189
183
|
|
|
190
|
-
// Test 5: Verify external tool wrapper type safety
|
|
191
184
|
logger.info('\nš§ Test 5: Testing TypeScript type safety');
|
|
192
185
|
|
|
193
|
-
// This should compile without type errors
|
|
194
186
|
const typedWrapper: ExternalToolWrapper<z.ZodObject<z.ZodRawShape, z.UnknownKeysParam, z.ZodTypeAny>> = wrappedTool;
|
|
195
187
|
const typedFormWrapper: FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape, z.UnknownKeysParam, z.ZodTypeAny>> = formValidatingTool;
|
|
196
188
|
|
|
@@ -198,17 +190,14 @@ async function testHederaKitWrapper(): Promise<void> {
|
|
|
198
190
|
logger.info(`ā
External wrapper type: ${typedWrapper.constructor.name}`);
|
|
199
191
|
logger.info(`ā
Form wrapper type: ${typedFormWrapper.constructor.name}`);
|
|
200
192
|
|
|
201
|
-
// Test 6: Verify tool delegation works
|
|
202
193
|
logger.info('\nš§ Test 6: Testing tool delegation');
|
|
203
194
|
|
|
204
|
-
|
|
205
|
-
logger.info(`ā
|
|
206
|
-
logger.info(`ā
|
|
207
|
-
logger.info(`ā
Form tool callable: ${typeof formValidatingTool._call === 'function'}`);
|
|
195
|
+
logger.info(`ā
Original tool callable: ${typeof (originalTool as any)._call === 'function'}`);
|
|
196
|
+
logger.info(`ā
Wrapped tool callable: ${typeof (wrappedTool as any)._call === 'function'}`);
|
|
197
|
+
logger.info(`ā
Form tool callable: ${typeof (formValidatingTool as any)._call === 'function'}`);
|
|
208
198
|
|
|
209
199
|
logger.info('\nš All external tool wrapper tests completed successfully!');
|
|
210
200
|
|
|
211
|
-
// Summary
|
|
212
201
|
logger.info('\nš Test Summary:');
|
|
213
202
|
logger.info('ā
External tool wrapping with render configs works');
|
|
214
203
|
logger.info('ā
Integration with FormValidatingToolWrapper works');
|
|
@@ -236,22 +225,18 @@ function demonstrateRenderConfigs(): void {
|
|
|
236
225
|
|
|
237
226
|
logger.info('\nšØ Demonstrating available render configurations:');
|
|
238
227
|
|
|
239
|
-
// Account-related configs
|
|
240
228
|
logger.info('\nš¤ Account Configurations:');
|
|
241
229
|
const accountConfig = renderConfigs.accountId('Target Account');
|
|
242
230
|
logger.info(`- Account ID: ${JSON.stringify(accountConfig, null, 2)}`);
|
|
243
231
|
|
|
244
|
-
// Currency configs
|
|
245
232
|
logger.info('\nš° Currency Configurations:');
|
|
246
233
|
const currencyConfig = renderConfigs.currency('Transfer Amount', 'HBAR', 0.00000001, 1000);
|
|
247
234
|
logger.info(`- Currency: ${JSON.stringify(currencyConfig, null, 2)}`);
|
|
248
235
|
|
|
249
|
-
// Token configs
|
|
250
236
|
logger.info('\nšŖ Token Configurations:');
|
|
251
237
|
const tokenConfig = renderConfigs.tokenId('Token to Transfer');
|
|
252
238
|
logger.info(`- Token ID: ${JSON.stringify(tokenConfig, null, 2)}`);
|
|
253
239
|
|
|
254
|
-
// Form control configs
|
|
255
240
|
logger.info('\nš Form Control Configurations:');
|
|
256
241
|
const textConfig = renderConfigs.text('Transaction Memo', 'Enter memo', 'Optional transaction memo');
|
|
257
242
|
const selectConfig = renderConfigs.select('Network', [
|
|
@@ -265,7 +250,6 @@ function demonstrateRenderConfigs(): void {
|
|
|
265
250
|
logger.info('\n⨠These configurations enhance hedera-agent-kit tools with rich UI metadata!');
|
|
266
251
|
}
|
|
267
252
|
|
|
268
|
-
// Run the test if this file is executed directly
|
|
269
253
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
270
254
|
testHederaKitWrapper()
|
|
271
255
|
.then(() => {
|