@hashgraphonline/conversational-agent 0.2.103 → 0.2.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -27
- package/cli/dist/CLIApp.d.ts +11 -0
- package/cli/dist/CLIApp.d.ts.map +1 -0
- package/cli/dist/CLIApp.js +128 -0
- package/cli/dist/CLIApp.js.map +1 -0
- package/cli/dist/LocalConversationalAgent.d.ts +37 -0
- package/cli/dist/LocalConversationalAgent.js +58 -0
- package/cli/dist/app.d.ts +18 -0
- package/cli/dist/app.d.ts.map +1 -0
- package/cli/dist/app.js +14 -0
- package/cli/dist/app.js.map +1 -0
- package/cli/dist/cli.d.ts +3 -0
- package/cli/dist/cli.d.ts.map +1 -0
- package/cli/dist/cli.js +87 -0
- package/cli/dist/cli.js.map +1 -0
- package/cli/dist/components/AppContainer.d.ts +16 -0
- package/cli/dist/components/AppContainer.js +24 -0
- package/cli/dist/components/AppScreens.d.ts +2 -0
- package/cli/dist/components/AppScreens.js +259 -0
- package/cli/dist/components/ChatScreen.d.ts +21 -0
- package/cli/dist/components/ChatScreen.d.ts.map +1 -0
- package/cli/dist/components/ChatScreen.js +40 -0
- package/cli/dist/components/ChatScreen.js.map +1 -0
- package/cli/dist/components/DebugLoadingScreen.d.ts +5 -0
- package/cli/dist/components/DebugLoadingScreen.js +31 -0
- package/cli/dist/components/LoadingScreen.d.ts +3 -0
- package/cli/dist/components/LoadingScreen.d.ts.map +1 -0
- package/cli/dist/components/LoadingScreen.js +17 -0
- package/cli/dist/components/LoadingScreen.js.map +1 -0
- package/cli/dist/components/LoadingScreenDebug.d.ts +5 -0
- package/cli/dist/components/LoadingScreenDebug.js +27 -0
- package/cli/dist/components/MCPConfigScreen.d.ts +28 -0
- package/cli/dist/components/MCPConfigScreen.d.ts.map +1 -0
- package/cli/dist/components/MCPConfigScreen.js +186 -0
- package/cli/dist/components/MCPConfigScreen.js.map +1 -0
- package/cli/dist/components/ScreenRouter.d.ts +13 -0
- package/cli/dist/components/ScreenRouter.d.ts.map +1 -0
- package/cli/dist/components/ScreenRouter.js +23 -0
- package/cli/dist/components/ScreenRouter.js.map +1 -0
- package/cli/dist/components/SetupScreen.d.ts +16 -0
- package/cli/dist/components/SetupScreen.d.ts.map +1 -0
- package/cli/dist/components/SetupScreen.js +67 -0
- package/cli/dist/components/SetupScreen.js.map +1 -0
- package/cli/dist/components/SingleLoadingScreen.d.ts +5 -0
- package/cli/dist/components/SingleLoadingScreen.js +27 -0
- package/cli/dist/components/StatusBadge.d.ts +10 -0
- package/cli/dist/components/StatusBadge.d.ts.map +1 -0
- package/cli/dist/components/StatusBadge.js +24 -0
- package/cli/dist/components/StatusBadge.js.map +1 -0
- package/cli/dist/components/TerminalWindow.d.ts +9 -0
- package/cli/dist/components/TerminalWindow.d.ts.map +1 -0
- package/cli/dist/components/TerminalWindow.js +19 -0
- package/cli/dist/components/TerminalWindow.js.map +1 -0
- package/cli/dist/components/WelcomeScreen.d.ts +12 -0
- package/cli/dist/components/WelcomeScreen.d.ts.map +1 -0
- package/cli/dist/components/WelcomeScreen.js +47 -0
- package/cli/dist/components/WelcomeScreen.js.map +1 -0
- package/cli/dist/context/AppContext.d.ts +68 -0
- package/cli/dist/context/AppContext.js +363 -0
- package/cli/dist/headless-runner.d.ts +17 -0
- package/cli/dist/headless-runner.d.ts.map +1 -0
- package/cli/dist/headless-runner.js +128 -0
- package/cli/dist/headless-runner.js.map +1 -0
- package/cli/dist/hooks/useInitializeAgent.d.ts +19 -0
- package/cli/dist/hooks/useInitializeAgent.d.ts.map +1 -0
- package/cli/dist/hooks/useInitializeAgent.js +29 -0
- package/cli/dist/hooks/useInitializeAgent.js.map +1 -0
- package/cli/dist/hooks/useStableState.d.ts +38 -0
- package/cli/dist/hooks/useStableState.d.ts.map +1 -0
- package/cli/dist/hooks/useStableState.js +69 -0
- package/cli/dist/hooks/useStableState.js.map +1 -0
- package/cli/dist/managers/AgentManager.d.ts +58 -0
- package/cli/dist/managers/AgentManager.d.ts.map +1 -0
- package/cli/dist/managers/AgentManager.js +121 -0
- package/cli/dist/managers/AgentManager.js.map +1 -0
- package/cli/dist/managers/ConfigManager.d.ts +54 -0
- package/cli/dist/managers/ConfigManager.d.ts.map +1 -0
- package/cli/dist/managers/ConfigManager.js +188 -0
- package/cli/dist/managers/ConfigManager.js.map +1 -0
- package/cli/dist/types.d.ts +52 -0
- package/cli/dist/types.d.ts.map +1 -0
- package/cli/dist/types.js +34 -0
- package/cli/dist/types.js.map +1 -0
- package/dist/cjs/config/system-message.d.ts +1 -1
- package/dist/cjs/conversational-agent.d.ts +30 -2
- package/dist/cjs/core/tool-registry.d.ts +29 -0
- package/dist/cjs/forms/field-guidance-registry.d.ts +33 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/mcp/types.d.ts +14 -3
- package/dist/cjs/plugins/index.d.ts +1 -0
- package/dist/cjs/plugins/inscribe/InscribePlugin.d.ts +1 -0
- package/dist/cjs/plugins/web-browser/WebBrowserPlugin.d.ts +14 -0
- package/dist/cjs/runtime/wallet-bridge.d.ts +26 -0
- package/dist/cjs/services/attachment-processor.d.ts +1 -2
- package/dist/cjs/services/content-store-manager.d.ts +1 -1
- package/dist/cjs/services/formatters/types.d.ts +3 -1
- package/dist/cjs/services/index.d.ts +1 -1
- package/dist/cjs/signers/browser-signer.d.ts +32 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index10.js +13 -5
- package/dist/esm/index10.js.map +1 -1
- package/dist/esm/index13.js +157 -179
- package/dist/esm/index13.js.map +1 -1
- package/dist/esm/index15.js +9 -4
- package/dist/esm/index15.js.map +1 -1
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index2.js +25 -27
- package/dist/esm/index2.js.map +1 -1
- package/dist/esm/index21.js +1 -1
- package/dist/esm/index21.js.map +1 -1
- package/dist/esm/index23.js +3 -3
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index26.js.map +1 -1
- package/dist/esm/index3.js.map +1 -1
- package/dist/esm/index30.js.map +1 -1
- package/dist/esm/index31.js +6 -3
- package/dist/esm/index31.js.map +1 -1
- package/dist/esm/index33.js +5 -5
- package/dist/esm/index33.js.map +1 -1
- package/dist/esm/index36.js +8 -45
- package/dist/esm/index36.js.map +1 -1
- package/dist/esm/index37.js +41 -102
- package/dist/esm/index37.js.map +1 -1
- package/dist/esm/index38.js +107 -21
- package/dist/esm/index38.js.map +1 -1
- package/dist/esm/index39.js +66 -12
- package/dist/esm/index39.js.map +1 -1
- package/dist/esm/index4.js +43 -0
- package/dist/esm/index4.js.map +1 -1
- package/dist/esm/index40.js +79 -7
- package/dist/esm/index40.js.map +1 -1
- package/dist/esm/index41.js +21 -5
- package/dist/esm/index41.js.map +1 -1
- package/dist/esm/index42.js +5 -255
- package/dist/esm/index42.js.map +1 -1
- package/dist/esm/index43.js +12 -184
- package/dist/esm/index43.js.map +1 -1
- package/dist/esm/index44.js +309 -79
- package/dist/esm/index44.js.map +1 -1
- package/dist/esm/index45.js +181 -24
- package/dist/esm/index45.js.map +1 -1
- package/dist/esm/index46.js +30 -0
- package/dist/esm/index46.js.map +1 -0
- package/dist/esm/index47.js +10 -0
- package/dist/esm/index47.js.map +1 -0
- package/dist/esm/index48.js +98 -0
- package/dist/esm/index48.js.map +1 -0
- package/dist/esm/index5.js +2 -2
- package/dist/esm/index6.js +231 -52
- package/dist/esm/index6.js.map +1 -1
- package/dist/types/config/system-message.d.ts +1 -1
- package/dist/types/conversational-agent.d.ts +30 -2
- package/dist/types/core/tool-registry.d.ts +29 -0
- package/dist/types/forms/field-guidance-registry.d.ts +33 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/mcp/types.d.ts +14 -3
- package/dist/types/plugins/index.d.ts +1 -0
- package/dist/types/plugins/inscribe/InscribePlugin.d.ts +1 -0
- package/dist/types/plugins/web-browser/WebBrowserPlugin.d.ts +14 -0
- package/dist/types/runtime/wallet-bridge.d.ts +26 -0
- package/dist/types/services/attachment-processor.d.ts +1 -2
- package/dist/types/services/content-store-manager.d.ts +1 -1
- package/dist/types/services/formatters/types.d.ts +3 -1
- package/dist/types/services/index.d.ts +1 -1
- package/dist/types/signers/browser-signer.d.ts +32 -0
- package/package.json +40 -37
- package/src/config/system-message.ts +3 -3
- package/src/conversational-agent.ts +356 -61
- package/src/core/tool-registry.ts +85 -0
- package/src/forms/field-guidance-registry.ts +213 -188
- package/src/forms/form-generator.ts +28 -12
- package/src/index.ts +1 -0
- package/src/langchain/form-aware-agent-executor.ts +6 -6
- package/src/langchain/langchain-agent.ts +1 -1
- package/src/mcp/mcp-client-manager.ts +12 -5
- package/src/mcp/types.ts +15 -3
- package/src/memory/content-storage.ts +19 -6
- package/src/memory/smart-memory-manager.ts +0 -1
- package/src/plugins/hbar/AccountBuilder.ts +16 -16
- package/src/plugins/hcs-10/HCS10Plugin.ts +38 -38
- package/src/plugins/hcs-2/HCS2Plugin.ts +2 -2
- package/src/plugins/index.ts +2 -1
- package/src/plugins/inscribe/InscribePlugin.ts +46 -2
- package/src/plugins/web-browser/WebBrowserPlugin.ts +128 -0
- package/src/runtime/wallet-bridge.ts +46 -0
- package/src/services/attachment-processor.ts +1 -1
- package/src/services/content-store-manager.ts +1 -1
- package/src/services/formatters/types.ts +3 -1
- package/src/services/index.ts +1 -1
- package/src/signers/browser-signer.ts +111 -0
- package/cli/readme.md +0 -181
|
@@ -979,9 +979,11 @@ export class FormAwareAgentExecutor extends AgentExecutor {
|
|
|
979
979
|
'🔗 HASHLINK DETECTED: Processing HashLink response separately to preserve metadata'
|
|
980
980
|
);
|
|
981
981
|
|
|
982
|
+
const parsedRecord = parsed as Record<string, unknown>;
|
|
982
983
|
responseMetadata = {
|
|
983
984
|
...responseMetadata,
|
|
984
|
-
hashLinkBlock:
|
|
985
|
+
hashLinkBlock: parsedRecord.hashLinkBlock,
|
|
986
|
+
...parsedRecord,
|
|
985
987
|
};
|
|
986
988
|
|
|
987
989
|
formattedOutput = ResponseFormatter.formatHashLinkResponse(parsed);
|
|
@@ -1003,6 +1005,7 @@ export class FormAwareAgentExecutor extends AgentExecutor {
|
|
|
1003
1005
|
responseMetadata = {
|
|
1004
1006
|
...responseMetadata,
|
|
1005
1007
|
hashLinkBlock: (parsed as Record<string, unknown>).hashLinkBlock,
|
|
1008
|
+
...parsed,
|
|
1006
1009
|
};
|
|
1007
1010
|
}
|
|
1008
1011
|
} else {
|
|
@@ -1240,6 +1243,7 @@ Please fill out the form below to continue.`;
|
|
|
1240
1243
|
}));
|
|
1241
1244
|
}
|
|
1242
1245
|
|
|
1246
|
+
|
|
1243
1247
|
/**
|
|
1244
1248
|
* Processes HashLink block responses from tools
|
|
1245
1249
|
*/
|
|
@@ -1251,11 +1255,7 @@ Please fill out the form below to continue.`;
|
|
|
1251
1255
|
|
|
1252
1256
|
if (toolResponse.hashLinkBlock) {
|
|
1253
1257
|
hashLinkBlock = toolResponse.hashLinkBlock;
|
|
1254
|
-
} else if (
|
|
1255
|
-
toolResponse.success &&
|
|
1256
|
-
toolResponse.inscription &&
|
|
1257
|
-
toolResponse.hashLinkBlock
|
|
1258
|
-
) {
|
|
1258
|
+
} else if (toolResponse.success && toolResponse.hashLinkBlock) {
|
|
1259
1259
|
hashLinkBlock = toolResponse.hashLinkBlock;
|
|
1260
1260
|
}
|
|
1261
1261
|
|
|
@@ -819,7 +819,7 @@ export class LangChainAgent extends BaseAgent {
|
|
|
819
819
|
if (args.metaOptions && typeof args.metaOptions === 'object') {
|
|
820
820
|
const metaOptions = args.metaOptions as Record<string, unknown>;
|
|
821
821
|
if (metaOptions.transactionMemo) {
|
|
822
|
-
|
|
822
|
+
this.logger.warn(
|
|
823
823
|
'🚨 WORKAROUND: Stripping transactionMemo from hedera-hts-mint-nft to avoid bug',
|
|
824
824
|
{ originalMemo: metaOptions.transactionMemo }
|
|
825
825
|
);
|
|
@@ -56,10 +56,17 @@ export class MCPClientManager {
|
|
|
56
56
|
this.clients.set(config.name, client);
|
|
57
57
|
|
|
58
58
|
const toolsResponse = await client.listTools();
|
|
59
|
-
const toolsWithServer: MCPToolInfo[] = toolsResponse.tools.map(tool =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
const toolsWithServer: MCPToolInfo[] = toolsResponse.tools.map((tool: unknown) => {
|
|
60
|
+
const t = tool as { description?: string } & Record<string, unknown>;
|
|
61
|
+
const { description, ...rest } = t;
|
|
62
|
+
const base = description !== undefined && typeof description === 'string'
|
|
63
|
+
? { ...rest, description }
|
|
64
|
+
: { ...rest };
|
|
65
|
+
return {
|
|
66
|
+
...(base as Omit<MCPToolInfo, 'serverName'>),
|
|
67
|
+
serverName: config.name,
|
|
68
|
+
} as MCPToolInfo;
|
|
69
|
+
});
|
|
63
70
|
|
|
64
71
|
this.tools.set(config.name, toolsWithServer);
|
|
65
72
|
this.logger.info(`Connected to MCP server ${config.name} with ${toolsWithServer.length} tools`);
|
|
@@ -205,4 +212,4 @@ export class MCPClientManager {
|
|
|
205
212
|
}
|
|
206
213
|
return this.contentProcessor.analyzeResponse(response);
|
|
207
214
|
}
|
|
208
|
-
}
|
|
215
|
+
}
|
package/src/mcp/types.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Minimal MCP Tool shape used internally to avoid external type dependency resolution issues.
|
|
3
|
+
* Aligns with MCP tool metadata returned by listTools.
|
|
4
|
+
*/
|
|
5
|
+
export interface BaseMCPTool {
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
/**
|
|
9
|
+
* JSON Schema describing input parameters for the tool.
|
|
10
|
+
* Kept as unknown and validated/converted at the boundary.
|
|
11
|
+
*/
|
|
12
|
+
inputSchema?: unknown;
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
export interface MCPServerConfig {
|
|
4
16
|
name: string;
|
|
@@ -17,7 +29,7 @@ export interface MCPServerConfig {
|
|
|
17
29
|
toolDescriptions?: Record<string, string>;
|
|
18
30
|
}
|
|
19
31
|
|
|
20
|
-
export interface MCPToolInfo extends
|
|
32
|
+
export interface MCPToolInfo extends BaseMCPTool {
|
|
21
33
|
serverName: string;
|
|
22
34
|
}
|
|
23
35
|
|
|
@@ -26,4 +38,4 @@ export interface MCPConnectionStatus {
|
|
|
26
38
|
connected: boolean;
|
|
27
39
|
error?: string;
|
|
28
40
|
tools: MCPToolInfo[];
|
|
29
|
-
}
|
|
41
|
+
}
|
|
@@ -317,7 +317,11 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
317
317
|
* Get the current storage configuration
|
|
318
318
|
* @returns Storage configuration object
|
|
319
319
|
*/
|
|
320
|
-
getConfig(): {
|
|
320
|
+
getConfig(): {
|
|
321
|
+
maxStorage: number;
|
|
322
|
+
currentUsage: number;
|
|
323
|
+
utilizationPercentage: number;
|
|
324
|
+
} {
|
|
321
325
|
return {
|
|
322
326
|
maxStorage: this.maxStorage,
|
|
323
327
|
currentUsage: this.messages.length,
|
|
@@ -354,11 +358,17 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
354
358
|
* Export messages to a JSON-serializable format
|
|
355
359
|
* @returns Serializable representation of stored messages
|
|
356
360
|
*/
|
|
357
|
-
exportMessages(): Array<{
|
|
361
|
+
exportMessages(): Array<{
|
|
362
|
+
content: string;
|
|
363
|
+
type: string;
|
|
364
|
+
storedAt: string;
|
|
365
|
+
id: string;
|
|
366
|
+
}> {
|
|
358
367
|
return this.messages.map((stored) => ({
|
|
359
|
-
content:
|
|
360
|
-
|
|
361
|
-
|
|
368
|
+
content:
|
|
369
|
+
typeof stored.message.content === 'string'
|
|
370
|
+
? stored.message.content
|
|
371
|
+
: JSON.stringify(stored.message.content),
|
|
362
372
|
type: stored.message._getType(),
|
|
363
373
|
storedAt: stored.storedAt.toISOString(),
|
|
364
374
|
id: stored.id,
|
|
@@ -832,7 +842,10 @@ export class ContentStorage implements ContentReferenceStore {
|
|
|
832
842
|
return new Date(Date.now() + policy.maxAgeMs);
|
|
833
843
|
}
|
|
834
844
|
|
|
835
|
-
private getCleanupPolicy(source: ContentSource): {
|
|
845
|
+
private getCleanupPolicy(source: ContentSource): {
|
|
846
|
+
maxAgeMs: number;
|
|
847
|
+
priority: number;
|
|
848
|
+
} {
|
|
836
849
|
switch (source) {
|
|
837
850
|
case 'mcp_tool':
|
|
838
851
|
return this.referenceConfig.cleanupPolicies.recent;
|
|
@@ -702,7 +702,6 @@ export class SmartMemoryManager {
|
|
|
702
702
|
}
|
|
703
703
|
}
|
|
704
704
|
|
|
705
|
-
// Merge duplicates by entityId, preferring the newest and one that carries transactionId
|
|
706
705
|
const mergedById = new Map<string, EntityAssociation>();
|
|
707
706
|
const getTime = (d: Date | string): number =>
|
|
708
707
|
d instanceof Date ? d.getTime() : new Date(d).getTime();
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AccountId,
|
|
3
|
-
Hbar,
|
|
4
|
-
TransferTransaction,
|
|
5
|
-
} from '@hashgraph/sdk';
|
|
1
|
+
import { AccountId, Hbar, TransferTransaction } from '@hashgraph/sdk';
|
|
6
2
|
import BigNumber from 'bignumber.js';
|
|
7
3
|
import { HederaAgentKit, BaseServiceBuilder } from 'hedera-agent-kit';
|
|
8
4
|
import { HbarTransferParams } from './types';
|
|
@@ -24,7 +20,7 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
24
20
|
): this {
|
|
25
21
|
this.clearNotes();
|
|
26
22
|
const transaction = new TransferTransaction();
|
|
27
|
-
|
|
23
|
+
|
|
28
24
|
if (!params.transfers || params.transfers.length === 0) {
|
|
29
25
|
throw new Error('HbarTransferParams must include at least one transfer.');
|
|
30
26
|
}
|
|
@@ -61,7 +57,7 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
61
57
|
this.kit.userAccountId
|
|
62
58
|
} to ${recipientAccountId.toString()}`
|
|
63
59
|
);
|
|
64
|
-
|
|
60
|
+
|
|
65
61
|
this.addNote(
|
|
66
62
|
`Configured HBAR transfer from your account (${
|
|
67
63
|
this.kit.userAccountId
|
|
@@ -84,7 +80,7 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
84
80
|
amount: BigNumber;
|
|
85
81
|
hbar: Hbar;
|
|
86
82
|
}> = [];
|
|
87
|
-
|
|
83
|
+
|
|
88
84
|
for (const transferInput of params.transfers) {
|
|
89
85
|
const accountId =
|
|
90
86
|
typeof transferInput.accountId === 'string'
|
|
@@ -99,7 +95,7 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
99
95
|
|
|
100
96
|
const amountBigNum = new BigNumber(amountValue);
|
|
101
97
|
const roundedAmount = amountBigNum.toFixed(8, BigNumber.ROUND_DOWN);
|
|
102
|
-
|
|
98
|
+
|
|
103
99
|
this.logger.info(
|
|
104
100
|
`Processing transfer: ${amountValue} HBAR (rounded to ${roundedAmount}) for account ${accountId.toString()}`
|
|
105
101
|
);
|
|
@@ -108,7 +104,7 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
108
104
|
processedTransfers.push({
|
|
109
105
|
accountId,
|
|
110
106
|
amount: amountBigNum,
|
|
111
|
-
hbar: sdkHbarAmount
|
|
107
|
+
hbar: sdkHbarAmount,
|
|
112
108
|
});
|
|
113
109
|
|
|
114
110
|
const tinybarsContribution = sdkHbarAmount.toTinybars();
|
|
@@ -121,20 +117,24 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
121
117
|
this.logger.warn(
|
|
122
118
|
`Transfer sum not zero: ${netZeroInTinybars.toString()} tinybars off. Adjusting last transfer.`
|
|
123
119
|
);
|
|
124
|
-
|
|
120
|
+
|
|
125
121
|
if (processedTransfers.length > 0) {
|
|
126
|
-
const lastTransfer =
|
|
122
|
+
const lastTransfer =
|
|
123
|
+
processedTransfers[processedTransfers.length - 1];
|
|
127
124
|
const adjustment = netZeroInTinybars.dividedBy(-100000000);
|
|
128
125
|
const adjustedAmount = lastTransfer.amount.plus(adjustment);
|
|
129
|
-
const adjustedRounded = adjustedAmount.toFixed(
|
|
126
|
+
const adjustedRounded = adjustedAmount.toFixed(
|
|
127
|
+
8,
|
|
128
|
+
BigNumber.ROUND_DOWN
|
|
129
|
+
);
|
|
130
130
|
lastTransfer.hbar = Hbar.fromString(adjustedRounded);
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
this.logger.info(
|
|
133
133
|
`Adjusted last transfer for ${lastTransfer.accountId.toString()} to ${adjustedRounded} HBAR`
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
|
|
138
138
|
for (const transfer of processedTransfers) {
|
|
139
139
|
transaction.addHbarTransfer(transfer.accountId, transfer.hbar);
|
|
140
140
|
}
|
|
@@ -151,4 +151,4 @@ export class AccountBuilder extends BaseServiceBuilder {
|
|
|
151
151
|
this.setCurrentTransaction(transaction);
|
|
152
152
|
return this;
|
|
153
153
|
}
|
|
154
|
-
}
|
|
154
|
+
}
|
|
@@ -19,33 +19,15 @@ import {
|
|
|
19
19
|
AcceptConnectionRequestTool,
|
|
20
20
|
RetrieveProfileTool,
|
|
21
21
|
ListUnapprovedConnectionRequestsTool,
|
|
22
|
+
RegisteredAgent,
|
|
22
23
|
} from '@hashgraphonline/standards-agent-kit';
|
|
23
24
|
import { HCS10Client } from '@hashgraphonline/standards-sdk';
|
|
25
|
+
import { PrivateKey } from 'node_modules/@hashgraph/sdk/lib/Mnemonic';
|
|
24
26
|
|
|
25
27
|
interface HCS10ClientManager {
|
|
26
28
|
initializeConnectionsManager(client: HCS10Client): void;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
/**
|
|
30
|
-
* Extracts private key string from operator key
|
|
31
|
-
*/
|
|
32
|
-
function extractPrivateKey(opKey: unknown): string {
|
|
33
|
-
const key = opKey as {
|
|
34
|
-
toString?: () => string;
|
|
35
|
-
toStringRaw?: () => string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
if (typeof key?.toStringRaw === 'function') {
|
|
39
|
-
return key.toStringRaw();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (typeof key?.toString === 'function') {
|
|
43
|
-
return key.toString();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return String(key);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
31
|
function hasInitializeConnectionsManager(
|
|
50
32
|
stateManager: IStateManager
|
|
51
33
|
): stateManager is IStateManager & HCS10ClientManager {
|
|
@@ -67,7 +49,7 @@ export class HCS10Plugin extends BasePlugin {
|
|
|
67
49
|
namespace = 'hcs10';
|
|
68
50
|
|
|
69
51
|
private stateManager?: IStateManager;
|
|
70
|
-
private tools:
|
|
52
|
+
private tools: any[] = [];
|
|
71
53
|
appConfig?: Record<string, unknown>;
|
|
72
54
|
|
|
73
55
|
override async initialize(context: GenericPluginContext): Promise<void> {
|
|
@@ -89,17 +71,27 @@ export class HCS10Plugin extends BasePlugin {
|
|
|
89
71
|
new OpenConvaiState();
|
|
90
72
|
|
|
91
73
|
const accountId = hederaKit.signer.getAccountId().toString();
|
|
74
|
+
const isBytesMode =
|
|
75
|
+
String(hederaKit.operationalMode || 'returnBytes') === 'returnBytes';
|
|
92
76
|
let inboundTopicId = '';
|
|
93
77
|
let outboundTopicId = '';
|
|
94
78
|
|
|
79
|
+
let operatorPrivateKeyRef: PrivateKey =
|
|
80
|
+
hederaKit.signer.getOperatorPrivateKey();
|
|
81
|
+
let operatorPrivateKeySerialized: string | undefined;
|
|
82
|
+
|
|
95
83
|
try {
|
|
96
|
-
const
|
|
97
|
-
|
|
84
|
+
const resolved =
|
|
85
|
+
typeof operatorPrivateKeyRef?.toString === 'function'
|
|
86
|
+
? operatorPrivateKeyRef.toString()
|
|
87
|
+
: '';
|
|
88
|
+
|
|
89
|
+
operatorPrivateKeySerialized = resolved;
|
|
98
90
|
|
|
99
91
|
const hcs10Client = new HCS10Client({
|
|
100
92
|
network: hederaKit.network as 'mainnet' | 'testnet',
|
|
101
93
|
operatorId: accountId,
|
|
102
|
-
operatorPrivateKey:
|
|
94
|
+
operatorPrivateKey: operatorPrivateKeyRef,
|
|
103
95
|
logLevel: 'error',
|
|
104
96
|
});
|
|
105
97
|
|
|
@@ -110,52 +102,60 @@ export class HCS10Plugin extends BasePlugin {
|
|
|
110
102
|
}
|
|
111
103
|
} catch (profileError) {
|
|
112
104
|
this.context.logger.warn(
|
|
113
|
-
'
|
|
105
|
+
'Skipping profile topic discovery',
|
|
114
106
|
profileError
|
|
115
107
|
);
|
|
116
108
|
}
|
|
117
109
|
|
|
118
|
-
|
|
110
|
+
const agentRecord: Record<string, unknown> = {
|
|
119
111
|
name: `Agent ${accountId}`,
|
|
120
112
|
accountId: accountId,
|
|
121
113
|
inboundTopicId,
|
|
122
114
|
outboundTopicId,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
115
|
+
};
|
|
116
|
+
if (!isBytesMode && operatorPrivateKeySerialized) {
|
|
117
|
+
agentRecord.privateKey = operatorPrivateKeySerialized;
|
|
118
|
+
}
|
|
119
|
+
this.stateManager.setCurrentAgent(
|
|
120
|
+
agentRecord as unknown as RegisteredAgent
|
|
121
|
+
);
|
|
128
122
|
|
|
129
123
|
this.context.logger.info(
|
|
130
124
|
`Set current agent: ${accountId} with topics ${inboundTopicId}/${outboundTopicId}`
|
|
131
125
|
);
|
|
132
126
|
|
|
133
|
-
if (
|
|
127
|
+
if (
|
|
128
|
+
!isBytesMode &&
|
|
129
|
+
this.stateManager &&
|
|
130
|
+
!this.stateManager.getConnectionsManager()
|
|
131
|
+
) {
|
|
134
132
|
try {
|
|
135
|
-
const opKey = hederaKit.signer.getOperatorPrivateKey();
|
|
136
|
-
const privateKey = extractPrivateKey(opKey);
|
|
137
133
|
const hcs10Client = new HCS10Client({
|
|
138
134
|
network: hederaKit.network as 'mainnet' | 'testnet',
|
|
139
135
|
operatorId: accountId,
|
|
140
|
-
operatorPrivateKey:
|
|
136
|
+
operatorPrivateKey: operatorPrivateKeyRef ?? '',
|
|
141
137
|
logLevel: 'error',
|
|
142
138
|
});
|
|
143
139
|
|
|
144
140
|
if (hasInitializeConnectionsManager(this.stateManager)) {
|
|
145
141
|
this.stateManager.initializeConnectionsManager(hcs10Client);
|
|
146
142
|
} else {
|
|
147
|
-
this.context.logger.warn(
|
|
143
|
+
this.context.logger.warn(
|
|
144
|
+
'StateManager does not support connection manager initialization'
|
|
145
|
+
);
|
|
148
146
|
}
|
|
149
147
|
this.context.logger.info(
|
|
150
148
|
'ConnectionsManager initialized in HCS10Plugin'
|
|
151
149
|
);
|
|
152
150
|
} catch (cmError) {
|
|
153
|
-
this.context.logger.warn(
|
|
151
|
+
this.context.logger.warn(
|
|
152
|
+
'Could not initialize ConnectionsManager:',
|
|
153
|
+
cmError
|
|
154
|
+
);
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
this.initializeTools();
|
|
158
|
-
|
|
159
159
|
this.context.logger.info('HCS-10 Plugin initialized successfully');
|
|
160
160
|
} catch (error) {
|
|
161
161
|
this.context.logger.error('Failed to initialize HCS-10 plugin:', error);
|
|
@@ -26,7 +26,7 @@ export class HCS2Plugin extends BasePlugin {
|
|
|
26
26
|
author = 'Hashgraph Online';
|
|
27
27
|
namespace = 'hcs2';
|
|
28
28
|
|
|
29
|
-
private tools:
|
|
29
|
+
private tools: any[] = [];
|
|
30
30
|
|
|
31
31
|
override async initialize(context: GenericPluginContext): Promise<void> {
|
|
32
32
|
await super.initialize(context);
|
|
@@ -105,4 +105,4 @@ export class HCS2Plugin extends BasePlugin {
|
|
|
105
105
|
this.context.logger.info('HCS-2 Plugin cleaned up');
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
-
}
|
|
108
|
+
}
|
package/src/plugins/index.ts
CHANGED
|
@@ -2,4 +2,5 @@ export { HCS10Plugin } from './hcs-10';
|
|
|
2
2
|
export { HCS2Plugin } from './hcs-2';
|
|
3
3
|
export { InscribePlugin } from './inscribe';
|
|
4
4
|
export { HbarPlugin } from './hbar/HbarPlugin';
|
|
5
|
-
export * from './hbar';
|
|
5
|
+
export * from './hbar';
|
|
6
|
+
export { WebBrowserPlugin } from './web-browser/WebBrowserPlugin';
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
InscribeHashinalTool,
|
|
13
13
|
RetrieveInscriptionTool,
|
|
14
14
|
} from '@hashgraphonline/standards-agent-kit';
|
|
15
|
+
import { fieldGuidanceRegistry, type FieldGuidance } from '../../forms/field-guidance-registry';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Plugin providing content inscription tools for Hedera
|
|
@@ -25,7 +26,8 @@ export class InscribePlugin extends BasePlugin {
|
|
|
25
26
|
author = 'Hashgraph Online';
|
|
26
27
|
namespace = 'inscribe';
|
|
27
28
|
|
|
28
|
-
private tools:
|
|
29
|
+
private tools: any[] = [];
|
|
30
|
+
private providerId: string | null = null;
|
|
29
31
|
|
|
30
32
|
override async initialize(context: GenericPluginContext): Promise<void> {
|
|
31
33
|
await super.initialize(context);
|
|
@@ -41,6 +43,42 @@ export class InscribePlugin extends BasePlugin {
|
|
|
41
43
|
try {
|
|
42
44
|
this.initializeTools();
|
|
43
45
|
|
|
46
|
+
try {
|
|
47
|
+
const provider = {
|
|
48
|
+
getFieldGuidance: (fieldName: string): FieldGuidance | null => {
|
|
49
|
+
if (fieldName === 'name') {
|
|
50
|
+
return {
|
|
51
|
+
suggestions: [
|
|
52
|
+
'Sunset Landscape #42',
|
|
53
|
+
'Digital Abstract Art',
|
|
54
|
+
],
|
|
55
|
+
contextualHelpText:
|
|
56
|
+
'Create a distinctive name that collectors will find appealing',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (fieldName === 'description') {
|
|
60
|
+
return {
|
|
61
|
+
fieldTypeOverride: 'textarea',
|
|
62
|
+
suggestions: ['A beautiful piece representing...'],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
},
|
|
67
|
+
getGlobalGuidance: () => ({
|
|
68
|
+
qualityStandards: [
|
|
69
|
+
'Use meaningful names that describe the artwork or content',
|
|
70
|
+
],
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
this.providerId = fieldGuidanceRegistry.registerToolProvider(
|
|
74
|
+
/hashinal/i,
|
|
75
|
+
provider,
|
|
76
|
+
{ id: 'inscribe:hashinal:provider', priority: 1 }
|
|
77
|
+
);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
this.context.logger.warn('Could not register Inscribe field guidance provider');
|
|
80
|
+
}
|
|
81
|
+
|
|
44
82
|
this.context.logger.info(
|
|
45
83
|
'Inscribe Plugin initialized successfully'
|
|
46
84
|
);
|
|
@@ -95,8 +133,14 @@ export class InscribePlugin extends BasePlugin {
|
|
|
95
133
|
|
|
96
134
|
override async cleanup(): Promise<void> {
|
|
97
135
|
this.tools = [];
|
|
136
|
+
if (this.providerId) {
|
|
137
|
+
try {
|
|
138
|
+
fieldGuidanceRegistry.unregisterProvider(this.providerId);
|
|
139
|
+
} catch {}
|
|
140
|
+
this.providerId = null;
|
|
141
|
+
}
|
|
98
142
|
if (this.context?.logger) {
|
|
99
143
|
this.context.logger.info('Inscribe Plugin cleaned up');
|
|
100
144
|
}
|
|
101
145
|
}
|
|
102
|
-
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BasePlugin,
|
|
3
|
+
type GenericPluginContext,
|
|
4
|
+
BaseHederaQueryTool,
|
|
5
|
+
type HederaAgentKit,
|
|
6
|
+
type HederaTool,
|
|
7
|
+
} from 'hedera-agent-kit';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
|
|
10
|
+
const PageSnapshotSchema = z.object({
|
|
11
|
+
url: z.string().url(),
|
|
12
|
+
maxCharacters: z
|
|
13
|
+
.number()
|
|
14
|
+
.int()
|
|
15
|
+
.min(256, 'Minimum length is 256 characters')
|
|
16
|
+
.max(8000, 'Maximum length is 8000 characters')
|
|
17
|
+
.optional()
|
|
18
|
+
.default(3000),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
class WebPageSnapshotTool extends BaseHederaQueryTool<typeof PageSnapshotSchema> {
|
|
22
|
+
name = 'web_page_snapshot';
|
|
23
|
+
description = 'Fetches the visible text content of a web page for analysis.';
|
|
24
|
+
namespace = 'browser';
|
|
25
|
+
specificInputSchema = PageSnapshotSchema;
|
|
26
|
+
|
|
27
|
+
constructor(params: {
|
|
28
|
+
hederaKit: HederaAgentKit;
|
|
29
|
+
logger?: GenericPluginContext['logger'];
|
|
30
|
+
fetchImpl?: typeof fetch;
|
|
31
|
+
}) {
|
|
32
|
+
const { fetchImpl, ...rest } = params;
|
|
33
|
+
super(rest);
|
|
34
|
+
this.fetchImpl = fetchImpl ?? fetch;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private readonly fetchImpl: typeof fetch;
|
|
38
|
+
|
|
39
|
+
protected async executeQuery(
|
|
40
|
+
input: z.infer<typeof PageSnapshotSchema>
|
|
41
|
+
): Promise<string> {
|
|
42
|
+
const maxChars = input.maxCharacters ?? 3000;
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const response = await this.fetchImpl(input.url, {
|
|
46
|
+
redirect: 'follow',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
return `Failed to load ${input.url}: HTTP ${response.status}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const html = await response.text();
|
|
54
|
+
const text = this.normalizeHtml(html);
|
|
55
|
+
|
|
56
|
+
if (!text) {
|
|
57
|
+
return 'The fetched page did not contain readable text.';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return text.length > maxChars ? `${text.slice(0, maxChars)}…` : text;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
this.logger.error('WebPageSnapshotTool failed', error);
|
|
63
|
+
return `Failed to fetch content for ${input.url}: ${
|
|
64
|
+
error instanceof Error ? error.message : String(error)
|
|
65
|
+
}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private normalizeHtml(html: string): string {
|
|
70
|
+
const withoutScripts = html
|
|
71
|
+
.replace(/<script[\s\S]*?<\/script>/gi, ' ')
|
|
72
|
+
.replace(/<style[\s\S]*?<\/style>/gi, ' ')
|
|
73
|
+
.replace(/<!--([\s\S]*?)-->/g, ' ');
|
|
74
|
+
|
|
75
|
+
const stripped = withoutScripts.replace(/<[^>]+>/g, ' ');
|
|
76
|
+
const decoded = stripped
|
|
77
|
+
.replace(/ /gi, ' ')
|
|
78
|
+
.replace(/&/gi, '&')
|
|
79
|
+
.replace(/</gi, '<')
|
|
80
|
+
.replace(/>/gi, '>')
|
|
81
|
+
.replace(/"/gi, '"')
|
|
82
|
+
.replace(/'/gi, "'");
|
|
83
|
+
|
|
84
|
+
return decoded.replace(/\s+/g, ' ').trim();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export class WebBrowserPlugin extends BasePlugin<GenericPluginContext> {
|
|
89
|
+
id = 'web-browser';
|
|
90
|
+
name = 'Web Browser Plugin';
|
|
91
|
+
description =
|
|
92
|
+
'Provides tools for fetching live web page content to enrich assistant understanding.';
|
|
93
|
+
version = '0.1.0';
|
|
94
|
+
author = 'Hashgraph Online';
|
|
95
|
+
namespace = 'browser';
|
|
96
|
+
|
|
97
|
+
private tools: HederaTool[] = [];
|
|
98
|
+
|
|
99
|
+
override async initialize(context: GenericPluginContext): Promise<void> {
|
|
100
|
+
await super.initialize(context);
|
|
101
|
+
|
|
102
|
+
const hederaKit = context.config.hederaKit as HederaAgentKit | undefined;
|
|
103
|
+
|
|
104
|
+
if (!hederaKit) {
|
|
105
|
+
this.context.logger.warn(
|
|
106
|
+
'WebBrowserPlugin skipped because HederaAgentKit was not present in plugin context.'
|
|
107
|
+
);
|
|
108
|
+
this.tools = [];
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const tool = new WebPageSnapshotTool({
|
|
113
|
+
hederaKit,
|
|
114
|
+
logger: this.context.logger,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
this.tools = [tool];
|
|
118
|
+
this.context.logger.info('Web Browser Plugin initialized with snapshot tool');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
override getTools(): HederaTool[] {
|
|
122
|
+
return this.tools;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
override async cleanup(): Promise<void> {
|
|
126
|
+
this.tools = [];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export type WalletNetwork = 'mainnet' | 'testnet';
|
|
2
|
+
|
|
3
|
+
export interface WalletStatus {
|
|
4
|
+
connected: boolean;
|
|
5
|
+
accountId?: string;
|
|
6
|
+
network?: WalletNetwork;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface WalletExecutorResult {
|
|
10
|
+
transactionId: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface StartInscriptionResult {
|
|
14
|
+
transactionBytes: string;
|
|
15
|
+
tx_id?: string;
|
|
16
|
+
topic_id?: string;
|
|
17
|
+
status?: string;
|
|
18
|
+
completed?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface WalletBridgeProvider {
|
|
22
|
+
status: () => Promise<WalletStatus> | WalletStatus;
|
|
23
|
+
executeBytes: (
|
|
24
|
+
base64: string,
|
|
25
|
+
network: WalletNetwork
|
|
26
|
+
) => Promise<WalletExecutorResult>;
|
|
27
|
+
startInscription?: (
|
|
28
|
+
request: Record<string, unknown>,
|
|
29
|
+
network: WalletNetwork
|
|
30
|
+
) => Promise<StartInscriptionResult>;
|
|
31
|
+
startHCS?: (
|
|
32
|
+
op: string,
|
|
33
|
+
request: Record<string, unknown>,
|
|
34
|
+
network: WalletNetwork
|
|
35
|
+
) => Promise<{ transactionBytes: string }>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let providerRef: WalletBridgeProvider | null = null;
|
|
39
|
+
|
|
40
|
+
export function setWalletBridgeProvider(provider: WalletBridgeProvider): void {
|
|
41
|
+
providerRef = provider;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getWalletBridgeProvider(): WalletBridgeProvider | null {
|
|
45
|
+
return providerRef;
|
|
46
|
+
}
|