@hashgraphonline/conversational-agent 0.2.104 → 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 +3 -1
- package/cli/dist/CLIApp.d.ts.map +1 -0
- package/cli/dist/CLIApp.js +6 -5
- package/cli/dist/CLIApp.js.map +1 -0
- package/cli/dist/app.d.ts +3 -1
- package/cli/dist/app.d.ts.map +1 -0
- package/cli/dist/app.js +2 -1
- package/cli/dist/app.js.map +1 -0
- package/cli/dist/cli.d.ts +1 -0
- package/cli/dist/cli.d.ts.map +1 -0
- package/cli/dist/cli.js +39 -3
- package/cli/dist/cli.js.map +1 -0
- package/cli/dist/components/ChatScreen.d.ts +9 -3
- package/cli/dist/components/ChatScreen.d.ts.map +1 -0
- package/cli/dist/components/ChatScreen.js +4 -3
- package/cli/dist/components/ChatScreen.js.map +1 -0
- package/cli/dist/components/LoadingScreen.d.ts +1 -0
- package/cli/dist/components/LoadingScreen.d.ts.map +1 -0
- package/cli/dist/components/LoadingScreen.js +2 -1
- package/cli/dist/components/LoadingScreen.js.map +1 -0
- package/cli/dist/components/MCPConfigScreen.d.ts +2 -2
- package/cli/dist/components/MCPConfigScreen.d.ts.map +1 -0
- package/cli/dist/components/MCPConfigScreen.js +77 -59
- package/cli/dist/components/MCPConfigScreen.js.map +1 -0
- package/cli/dist/components/ScreenRouter.d.ts +1 -0
- package/cli/dist/components/ScreenRouter.d.ts.map +1 -0
- package/cli/dist/components/ScreenRouter.js +6 -5
- package/cli/dist/components/ScreenRouter.js.map +1 -0
- package/cli/dist/components/SetupScreen.d.ts +1 -0
- package/cli/dist/components/SetupScreen.d.ts.map +1 -0
- package/cli/dist/components/SetupScreen.js +28 -26
- package/cli/dist/components/SetupScreen.js.map +1 -0
- package/cli/dist/components/StatusBadge.d.ts +4 -1
- package/cli/dist/components/StatusBadge.d.ts.map +1 -0
- package/cli/dist/components/StatusBadge.js +18 -22
- package/cli/dist/components/StatusBadge.js.map +1 -0
- package/cli/dist/components/TerminalWindow.d.ts +1 -0
- package/cli/dist/components/TerminalWindow.d.ts.map +1 -0
- package/cli/dist/components/TerminalWindow.js +2 -7
- package/cli/dist/components/TerminalWindow.js.map +1 -0
- package/cli/dist/components/WelcomeScreen.d.ts +1 -0
- package/cli/dist/components/WelcomeScreen.d.ts.map +1 -0
- package/cli/dist/components/WelcomeScreen.js +15 -15
- package/cli/dist/components/WelcomeScreen.js.map +1 -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 +4 -4
- package/cli/dist/hooks/useInitializeAgent.d.ts.map +1 -0
- package/cli/dist/hooks/useInitializeAgent.js +1 -0
- package/cli/dist/hooks/useInitializeAgent.js.map +1 -0
- package/cli/dist/hooks/useStableState.d.ts +2 -2
- package/cli/dist/hooks/useStableState.d.ts.map +1 -0
- package/cli/dist/hooks/useStableState.js +1 -0
- package/cli/dist/hooks/useStableState.js.map +1 -0
- package/cli/dist/managers/AgentManager.d.ts +3 -2
- package/cli/dist/managers/AgentManager.d.ts.map +1 -0
- package/cli/dist/managers/AgentManager.js +8 -6
- package/cli/dist/managers/AgentManager.js.map +1 -0
- package/cli/dist/managers/ConfigManager.d.ts +3 -2
- package/cli/dist/managers/ConfigManager.d.ts.map +1 -0
- package/cli/dist/managers/ConfigManager.js +23 -8
- package/cli/dist/managers/ConfigManager.js.map +1 -0
- package/cli/dist/types.d.ts +22 -1
- package/cli/dist/types.d.ts.map +1 -0
- package/cli/dist/types.js +15 -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 +63 -24
- 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 +78 -11
- 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 +322 -7
- package/dist/esm/index44.js.map +1 -1
- package/dist/esm/index45.js +174 -82
- 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 +189 -29
- 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 +16 -11
- package/src/config/system-message.ts +3 -3
- package/src/conversational-agent.ts +318 -45
- 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
|
@@ -2,13 +2,14 @@ import {
|
|
|
2
2
|
ServerSigner,
|
|
3
3
|
getAllHederaCorePlugins,
|
|
4
4
|
BasePlugin,
|
|
5
|
+
AbstractSigner,
|
|
5
6
|
} from 'hedera-agent-kit';
|
|
6
7
|
import { Logger, type NetworkType } from '@hashgraphonline/standards-sdk';
|
|
7
8
|
import { createAgent } from './agent-factory';
|
|
9
|
+
import BrowserSigner from './signers/browser-signer';
|
|
8
10
|
import { LangChainProvider } from './providers';
|
|
9
11
|
import type { ChatResponse, ConversationContext } from './base-agent';
|
|
10
12
|
import { ChatOpenAI } from '@langchain/openai';
|
|
11
|
-
import OpenAI from 'openai';
|
|
12
13
|
import { ChatAnthropic } from '@langchain/anthropic';
|
|
13
14
|
import {
|
|
14
15
|
HumanMessage,
|
|
@@ -19,7 +20,13 @@ import type { AgentOperationalMode, MirrorNodeConfig } from 'hedera-agent-kit';
|
|
|
19
20
|
import { HCS10Plugin } from './plugins/hcs-10/HCS10Plugin';
|
|
20
21
|
import { HCS2Plugin } from './plugins/hcs-2/HCS2Plugin';
|
|
21
22
|
import { InscribePlugin } from './plugins/inscribe/InscribePlugin';
|
|
23
|
+
import { getWalletBridgeProvider } from './runtime/wallet-bridge';
|
|
24
|
+
import {
|
|
25
|
+
InscriberBuilder,
|
|
26
|
+
SignerProviderRegistry,
|
|
27
|
+
} from '@hashgraphonline/standards-agent-kit';
|
|
22
28
|
import { HbarPlugin } from './plugins/hbar/HbarPlugin';
|
|
29
|
+
import { WebBrowserPlugin } from './plugins/web-browser/WebBrowserPlugin';
|
|
23
30
|
import { OpenConvaiState } from '@hashgraphonline/standards-agent-kit';
|
|
24
31
|
import type { IStateManager } from '@hashgraphonline/standards-agent-kit';
|
|
25
32
|
import { getSystemMessage } from './config/system-message';
|
|
@@ -52,6 +59,9 @@ export type AgentInstance = ReturnType<typeof createAgent>;
|
|
|
52
59
|
export type MirrorNetwork = 'testnet' | 'mainnet' | 'previewnet';
|
|
53
60
|
|
|
54
61
|
const DEFAULT_MODEL_NAME = 'gpt-4o';
|
|
62
|
+
const DEFAULT_OPENAI_MODEL = 'gpt-4o-mini';
|
|
63
|
+
const DEFAULT_OPENROUTER_MODEL = 'openai/gpt-4o-mini';
|
|
64
|
+
const DEFAULT_CLAUDE_MODEL = 'claude-3-7-sonnet-latest';
|
|
55
65
|
const DEFAULT_TEMPERATURE = 0.1;
|
|
56
66
|
const DEFAULT_NETWORK = 'testnet';
|
|
57
67
|
const DEFAULT_OPERATIONAL_MODE: AgentOperationalMode = 'autonomous';
|
|
@@ -74,8 +84,19 @@ export interface ConversationalAgentOptions {
|
|
|
74
84
|
mirrorNodeConfig?: MirrorNodeConfig;
|
|
75
85
|
disableLogging?: boolean;
|
|
76
86
|
enabledPlugins?: string[];
|
|
87
|
+
disabledPlugins?: string[];
|
|
77
88
|
toolFilter?: (tool: { name: string; namespace?: string }) => boolean;
|
|
78
89
|
mcpServers?: MCPServerConfig[];
|
|
90
|
+
walletExecutor?: (
|
|
91
|
+
base64: string,
|
|
92
|
+
network: 'mainnet' | 'testnet'
|
|
93
|
+
) => Promise<{ transactionId: string }>;
|
|
94
|
+
/** Optional: provide a signer factory to override default signer selection */
|
|
95
|
+
customSignerFactory?: (args: {
|
|
96
|
+
operationalMode: AgentOperationalMode;
|
|
97
|
+
accountId: string;
|
|
98
|
+
network: NetworkType;
|
|
99
|
+
}) => AbstractSigner;
|
|
79
100
|
|
|
80
101
|
/** Enable automatic entity memory functionality (default: true) */
|
|
81
102
|
entityMemoryEnabled?: boolean;
|
|
@@ -114,6 +135,7 @@ export class ConversationalAgent {
|
|
|
114
135
|
public hcs2Plugin: HCS2Plugin;
|
|
115
136
|
public inscribePlugin: InscribePlugin;
|
|
116
137
|
public hbarPlugin: HbarPlugin;
|
|
138
|
+
public webBrowserPlugin: WebBrowserPlugin;
|
|
117
139
|
public stateManager: IStateManager;
|
|
118
140
|
private options: ConversationalAgentOptions;
|
|
119
141
|
public logger: Logger;
|
|
@@ -131,6 +153,7 @@ export class ConversationalAgent {
|
|
|
131
153
|
this.hcs2Plugin = new HCS2Plugin();
|
|
132
154
|
this.inscribePlugin = new InscribePlugin();
|
|
133
155
|
this.hbarPlugin = new HbarPlugin();
|
|
156
|
+
this.webBrowserPlugin = new WebBrowserPlugin();
|
|
134
157
|
this.logger = new Logger({
|
|
135
158
|
module: 'ConversationalAgent',
|
|
136
159
|
silent: options.disableLogging || false,
|
|
@@ -148,14 +171,18 @@ export class ConversationalAgent {
|
|
|
148
171
|
);
|
|
149
172
|
this.logger.info('Entity memory initialized');
|
|
150
173
|
|
|
151
|
-
const provider =
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
174
|
+
const provider =
|
|
175
|
+
options.entityMemoryProvider || options.llmProvider || 'openai';
|
|
176
|
+
let modelName = options.entityMemoryModelName;
|
|
177
|
+
if (!modelName) {
|
|
178
|
+
if (provider === 'anthropic') {
|
|
179
|
+
modelName = DEFAULT_CLAUDE_MODEL;
|
|
180
|
+
} else if (provider === 'openrouter') {
|
|
181
|
+
modelName = DEFAULT_OPENROUTER_MODEL;
|
|
182
|
+
} else {
|
|
183
|
+
modelName = DEFAULT_OPENAI_MODEL;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
159
186
|
|
|
160
187
|
let resolverLLM: ChatOpenAI | ChatAnthropic;
|
|
161
188
|
if (provider === 'anthropic') {
|
|
@@ -165,7 +192,8 @@ export class ConversationalAgent {
|
|
|
165
192
|
temperature: 0,
|
|
166
193
|
});
|
|
167
194
|
} else if (provider === 'openrouter') {
|
|
168
|
-
const baseURL =
|
|
195
|
+
const baseURL =
|
|
196
|
+
options.openRouterBaseURL || 'https://openrouter.ai/api/v1';
|
|
169
197
|
const apiKey = options.openRouterApiKey || options.openAIApiKey;
|
|
170
198
|
resolverLLM = new ChatOpenAI({
|
|
171
199
|
apiKey,
|
|
@@ -174,8 +202,12 @@ export class ConversationalAgent {
|
|
|
174
202
|
configuration: {
|
|
175
203
|
baseURL,
|
|
176
204
|
defaultHeaders: {
|
|
177
|
-
'HTTP-Referer':
|
|
178
|
-
|
|
205
|
+
'HTTP-Referer':
|
|
206
|
+
process.env.OPENROUTER_REFERRER ||
|
|
207
|
+
'https://hashgraphonline.com',
|
|
208
|
+
'X-Title':
|
|
209
|
+
process.env.OPENROUTER_TITLE ||
|
|
210
|
+
'Hashgraph Online Conversational Agent',
|
|
179
211
|
},
|
|
180
212
|
},
|
|
181
213
|
});
|
|
@@ -210,29 +242,213 @@ export class ConversationalAgent {
|
|
|
210
242
|
this.validateOptions(accountId, privateKey);
|
|
211
243
|
|
|
212
244
|
try {
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
245
|
+
const opMode = (this.options.operationalMode ||
|
|
246
|
+
DEFAULT_OPERATIONAL_MODE) as string;
|
|
247
|
+
const bytesMode = opMode !== 'autonomous';
|
|
248
|
+
let signer: AbstractSigner;
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
type InscriberBuilderWithWalletMethods = typeof InscriberBuilder & {
|
|
252
|
+
setPreferWalletOnly?: (prefer: boolean) => void;
|
|
253
|
+
setWalletInfoResolver?: (
|
|
254
|
+
fn: () => Promise<{ accountId: string; network: string } | null>
|
|
255
|
+
) => void;
|
|
256
|
+
setWalletExecutor?: (
|
|
257
|
+
fn: (
|
|
258
|
+
base64: string,
|
|
259
|
+
network: 'mainnet' | 'testnet'
|
|
260
|
+
) => Promise<{ transactionId: string }>
|
|
261
|
+
) => void;
|
|
262
|
+
setStartInscriptionDelegate?: (
|
|
263
|
+
fn: (
|
|
264
|
+
request: Record<string, unknown>,
|
|
265
|
+
network: 'mainnet' | 'testnet'
|
|
266
|
+
) => Promise<unknown>
|
|
267
|
+
) => void;
|
|
268
|
+
};
|
|
269
|
+
const IB = InscriberBuilder as InscriberBuilderWithWalletMethods;
|
|
270
|
+
if (typeof IB.setPreferWalletOnly === 'function') {
|
|
271
|
+
IB.setPreferWalletOnly(false);
|
|
272
|
+
}
|
|
273
|
+
} catch (e) {
|
|
274
|
+
this.logger.warn('Failed to set wallet-only preference', e as Error);
|
|
275
|
+
}
|
|
276
|
+
if (!bytesMode) {
|
|
277
|
+
signer = new ServerSigner(
|
|
278
|
+
accountId!,
|
|
279
|
+
privateKey!,
|
|
280
|
+
network as MirrorNetwork
|
|
281
|
+
);
|
|
282
|
+
} else {
|
|
283
|
+
const chain: 'mainnet' | 'testnet' =
|
|
284
|
+
String(network || 'testnet') === 'mainnet' ? 'mainnet' : 'testnet';
|
|
285
|
+
const effectiveAccount = (this.options.userAccountId || accountId)!;
|
|
286
|
+
signer = new BrowserSigner(
|
|
287
|
+
effectiveAccount,
|
|
288
|
+
chain,
|
|
289
|
+
this.options.walletExecutor
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
this.logger.info('Signer configured', {
|
|
294
|
+
operationalMode: opMode,
|
|
295
|
+
bytesMode,
|
|
296
|
+
signerClass:
|
|
297
|
+
Object.getPrototypeOf(signer)?.constructor?.name || 'unknown',
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
const bridge = getWalletBridgeProvider();
|
|
302
|
+
if (bridge) {
|
|
303
|
+
type InscriberBuilderWithWalletMethods = typeof InscriberBuilder & {
|
|
304
|
+
setWalletInfoResolver?: (
|
|
305
|
+
fn: () => Promise<{ accountId: string; network: string } | null>
|
|
306
|
+
) => void;
|
|
307
|
+
setWalletExecutor?: (
|
|
308
|
+
fn: (
|
|
309
|
+
base64: string,
|
|
310
|
+
network: 'mainnet' | 'testnet'
|
|
311
|
+
) => Promise<{ transactionId: string }>
|
|
312
|
+
) => void;
|
|
313
|
+
setStartInscriptionDelegate?: (
|
|
314
|
+
fn: (
|
|
315
|
+
request: Record<string, unknown>,
|
|
316
|
+
network: 'mainnet' | 'testnet'
|
|
317
|
+
) => Promise<unknown>
|
|
318
|
+
) => void;
|
|
319
|
+
};
|
|
320
|
+
const IB = InscriberBuilder as InscriberBuilderWithWalletMethods;
|
|
321
|
+
if (typeof IB.setWalletInfoResolver === 'function') {
|
|
322
|
+
IB.setWalletInfoResolver(async () => {
|
|
323
|
+
const status = await bridge.status();
|
|
324
|
+
if (status.connected && status.accountId && status.network) {
|
|
325
|
+
return { accountId: status.accountId, network: status.network };
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
if (typeof IB.setWalletExecutor === 'function') {
|
|
331
|
+
IB.setWalletExecutor(
|
|
332
|
+
async (base64: string, network: 'mainnet' | 'testnet') => {
|
|
333
|
+
return await bridge.executeBytes(base64, network);
|
|
334
|
+
}
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
if (
|
|
338
|
+
typeof IB.setStartInscriptionDelegate === 'function' &&
|
|
339
|
+
bridge.startInscription
|
|
340
|
+
) {
|
|
341
|
+
IB.setStartInscriptionDelegate(
|
|
342
|
+
async (
|
|
343
|
+
request: Record<string, unknown>,
|
|
344
|
+
network: 'mainnet' | 'testnet'
|
|
345
|
+
) => {
|
|
346
|
+
return await bridge.startInscription!(request, network);
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
try {
|
|
352
|
+
type HCSOp =
|
|
353
|
+
| 'submitConnectionRequest'
|
|
354
|
+
| 'handleConnectionRequest'
|
|
355
|
+
| 'sendMessage'
|
|
356
|
+
| 'hcs2.createRegistry'
|
|
357
|
+
| 'hcs2.migrateRegistry'
|
|
358
|
+
| 'hcs2.registerEntry'
|
|
359
|
+
| 'hcs2.updateEntry'
|
|
360
|
+
| 'hcs2.deleteEntry'
|
|
361
|
+
| 'hcs2.submitMessage'
|
|
362
|
+
| 'hcs6.createRegistry'
|
|
363
|
+
| 'hcs6.registerEntry'
|
|
364
|
+
| 'hcs6.submitMessage';
|
|
365
|
+
type WalletBridgeProviderExt = ReturnType<
|
|
366
|
+
typeof getWalletBridgeProvider
|
|
367
|
+
> & {
|
|
368
|
+
startHCS?: (
|
|
369
|
+
op: HCSOp,
|
|
370
|
+
request: Record<string, unknown>,
|
|
371
|
+
network: 'mainnet' | 'testnet'
|
|
372
|
+
) => Promise<{ transactionBytes: string }>;
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const status = await bridge.status();
|
|
376
|
+
const enforceWallet = !!(bytesMode && status.connected);
|
|
377
|
+
|
|
378
|
+
SignerProviderRegistry.setWalletInfoResolver(async () => {
|
|
379
|
+
const s = await bridge.status();
|
|
380
|
+
if (s.connected && s.accountId && s.network) {
|
|
381
|
+
return {
|
|
382
|
+
accountId: s.accountId,
|
|
383
|
+
network: s.network as 'mainnet' | 'testnet',
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
return null;
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
SignerProviderRegistry.setWalletExecutor(
|
|
390
|
+
async (base64: string, network: 'mainnet' | 'testnet') => {
|
|
391
|
+
return await bridge.executeBytes(base64, network);
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
const extended = bridge as WalletBridgeProviderExt;
|
|
396
|
+
if (typeof extended?.startHCS === 'function') {
|
|
397
|
+
SignerProviderRegistry.setStartHCSDelegate(
|
|
398
|
+
async (op, request, network) => {
|
|
399
|
+
return await extended.startHCS!(
|
|
400
|
+
op as HCSOp,
|
|
401
|
+
request,
|
|
402
|
+
network
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
);
|
|
406
|
+
} else {
|
|
407
|
+
SignerProviderRegistry.setStartHCSDelegate(null);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
SignerProviderRegistry.setPreferWalletOnly(enforceWallet);
|
|
411
|
+
|
|
412
|
+
type InscriberBuilderWithWalletMethods = typeof InscriberBuilder & {
|
|
413
|
+
setPreferWalletOnly?: (prefer: boolean) => void;
|
|
414
|
+
};
|
|
415
|
+
const IB2 = InscriberBuilder as InscriberBuilderWithWalletMethods;
|
|
416
|
+
if (typeof IB2.setPreferWalletOnly === 'function') {
|
|
417
|
+
IB2.setPreferWalletOnly(enforceWallet);
|
|
418
|
+
}
|
|
419
|
+
} catch (sakWireErr) {
|
|
420
|
+
this.logger.warn(
|
|
421
|
+
'Failed to wire SAK SignerProviderRegistry wallet delegates',
|
|
422
|
+
sakWireErr as Error
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
} catch (e) {
|
|
427
|
+
this.logger.warn(
|
|
428
|
+
'Failed to register wallet bridge providers',
|
|
429
|
+
e as Error
|
|
430
|
+
);
|
|
431
|
+
}
|
|
218
432
|
|
|
219
433
|
let llm: ChatOpenAI | ChatAnthropic;
|
|
220
434
|
let providerInfo: Record<string, unknown> = { provider: llmProvider };
|
|
221
435
|
if (llmProvider === 'anthropic') {
|
|
222
436
|
llm = new ChatAnthropic({
|
|
223
437
|
apiKey: openAIApiKey,
|
|
224
|
-
model: openAIModelName ||
|
|
438
|
+
model: openAIModelName || DEFAULT_CLAUDE_MODEL,
|
|
225
439
|
temperature: DEFAULT_TEMPERATURE,
|
|
226
440
|
});
|
|
227
441
|
providerInfo = {
|
|
228
442
|
...providerInfo,
|
|
229
|
-
model: openAIModelName ||
|
|
443
|
+
model: openAIModelName || DEFAULT_CLAUDE_MODEL,
|
|
230
444
|
keyPresent: !!openAIApiKey,
|
|
231
445
|
};
|
|
232
446
|
} else if (llmProvider === 'openrouter') {
|
|
233
|
-
const baseURL =
|
|
447
|
+
const baseURL =
|
|
448
|
+
this.options.openRouterBaseURL || 'https://openrouter.ai/api/v1';
|
|
234
449
|
const apiKey = this.options.openRouterApiKey || openAIApiKey;
|
|
235
|
-
const modelName =
|
|
450
|
+
const modelName =
|
|
451
|
+
openAIModelName || 'anthropic/claude-3-haiku-20240307';
|
|
236
452
|
llm = new ChatOpenAI({
|
|
237
453
|
apiKey,
|
|
238
454
|
model: modelName,
|
|
@@ -240,8 +456,12 @@ export class ConversationalAgent {
|
|
|
240
456
|
configuration: {
|
|
241
457
|
baseURL,
|
|
242
458
|
defaultHeaders: {
|
|
243
|
-
'HTTP-Referer':
|
|
244
|
-
|
|
459
|
+
'HTTP-Referer':
|
|
460
|
+
process.env.OPENROUTER_REFERRER ||
|
|
461
|
+
'https://hashgraphonline.com',
|
|
462
|
+
'X-Title':
|
|
463
|
+
process.env.OPENROUTER_TITLE ||
|
|
464
|
+
'Hashgraph Online Conversational Agent',
|
|
245
465
|
},
|
|
246
466
|
},
|
|
247
467
|
});
|
|
@@ -252,20 +472,20 @@ export class ConversationalAgent {
|
|
|
252
472
|
keyPresent: !!apiKey,
|
|
253
473
|
};
|
|
254
474
|
} else {
|
|
255
|
-
const
|
|
475
|
+
const modelName2 = openAIModelName || DEFAULT_OPENAI_MODEL;
|
|
256
476
|
const isGPT5Model =
|
|
257
|
-
|
|
258
|
-
|
|
477
|
+
modelName2.toLowerCase().includes('gpt-5') ||
|
|
478
|
+
modelName2.toLowerCase().includes('gpt5');
|
|
259
479
|
llm = new ChatOpenAI({
|
|
260
480
|
apiKey: openAIApiKey,
|
|
261
|
-
model:
|
|
481
|
+
model: modelName2,
|
|
262
482
|
...(isGPT5Model
|
|
263
483
|
? { temperature: 1 }
|
|
264
484
|
: { temperature: DEFAULT_TEMPERATURE }),
|
|
265
485
|
});
|
|
266
486
|
providerInfo = {
|
|
267
487
|
...providerInfo,
|
|
268
|
-
model:
|
|
488
|
+
model: modelName2,
|
|
269
489
|
keyPresent: !!openAIApiKey,
|
|
270
490
|
};
|
|
271
491
|
}
|
|
@@ -275,7 +495,11 @@ export class ConversationalAgent {
|
|
|
275
495
|
this.logger.info('Preparing plugins...');
|
|
276
496
|
const allPlugins = this.preparePlugins();
|
|
277
497
|
this.logger.info('Creating agent config...');
|
|
278
|
-
const agentConfig = this.createAgentConfig(
|
|
498
|
+
const agentConfig = this.createAgentConfig(
|
|
499
|
+
signer as ServerSigner,
|
|
500
|
+
llm,
|
|
501
|
+
allPlugins
|
|
502
|
+
);
|
|
279
503
|
|
|
280
504
|
this.logger.info('Creating agent...');
|
|
281
505
|
this.agent = createAgent(agentConfig);
|
|
@@ -472,8 +696,14 @@ export class ConversationalAgent {
|
|
|
472
696
|
* @throws {Error} If required fields are missing
|
|
473
697
|
*/
|
|
474
698
|
private validateOptions(accountId?: string, privateKey?: string): void {
|
|
475
|
-
|
|
476
|
-
|
|
699
|
+
const opMode = (this.options.operationalMode ||
|
|
700
|
+
DEFAULT_OPERATIONAL_MODE) as string;
|
|
701
|
+
const bytesMode = opMode !== 'autonomous';
|
|
702
|
+
if (!accountId) {
|
|
703
|
+
throw new Error('Account ID is required');
|
|
704
|
+
}
|
|
705
|
+
if (!privateKey && !bytesMode) {
|
|
706
|
+
throw new Error('Private key is required in autonomous mode');
|
|
477
707
|
}
|
|
478
708
|
|
|
479
709
|
if (typeof accountId !== 'string') {
|
|
@@ -482,15 +712,18 @@ export class ConversationalAgent {
|
|
|
482
712
|
);
|
|
483
713
|
}
|
|
484
714
|
|
|
485
|
-
if (typeof privateKey !== 'string') {
|
|
715
|
+
if (!bytesMode && typeof privateKey !== 'string') {
|
|
486
716
|
throw new Error(
|
|
487
717
|
`Private key must be a string, received ${typeof privateKey}: ${JSON.stringify(
|
|
488
718
|
privateKey
|
|
489
719
|
)}`
|
|
490
720
|
);
|
|
491
721
|
}
|
|
492
|
-
|
|
493
|
-
|
|
722
|
+
if (
|
|
723
|
+
!bytesMode &&
|
|
724
|
+
typeof privateKey === 'string' &&
|
|
725
|
+
privateKey.length < 10
|
|
726
|
+
) {
|
|
494
727
|
throw new Error('Private key appears to be invalid (too short)');
|
|
495
728
|
}
|
|
496
729
|
}
|
|
@@ -501,38 +734,46 @@ export class ConversationalAgent {
|
|
|
501
734
|
* @returns Array of plugins to initialize with the agent
|
|
502
735
|
*/
|
|
503
736
|
private preparePlugins(): BasePlugin[] {
|
|
504
|
-
const { additionalPlugins = [], enabledPlugins } = this.options;
|
|
737
|
+
const { additionalPlugins = [], enabledPlugins, disabledPlugins } = this.options;
|
|
505
738
|
|
|
506
|
-
const standardPlugins = [
|
|
739
|
+
const standardPlugins: BasePlugin[] = [
|
|
507
740
|
this.hcs10Plugin,
|
|
508
741
|
this.hcs2Plugin,
|
|
509
742
|
this.inscribePlugin,
|
|
510
743
|
this.hbarPlugin,
|
|
511
744
|
];
|
|
745
|
+
standardPlugins.push(this.webBrowserPlugin);
|
|
512
746
|
|
|
513
747
|
const corePlugins = getAllHederaCorePlugins();
|
|
748
|
+
let pluginPool = [...standardPlugins, ...corePlugins];
|
|
514
749
|
|
|
515
750
|
if (enabledPlugins) {
|
|
516
751
|
const enabledSet = new Set(enabledPlugins);
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
752
|
+
pluginPool = pluginPool.filter((plugin) => enabledSet.has(plugin.id));
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
if (disabledPlugins && disabledPlugins.length > 0) {
|
|
756
|
+
const disabledSet = new Set(disabledPlugins);
|
|
757
|
+
pluginPool = pluginPool.filter((plugin) => !disabledSet.has(plugin.id));
|
|
521
758
|
}
|
|
522
759
|
|
|
523
|
-
|
|
760
|
+
const additional = disabledPlugins && disabledPlugins.length > 0
|
|
761
|
+
? additionalPlugins.filter((plugin) => !disabledPlugins.includes(plugin.id))
|
|
762
|
+
: additionalPlugins;
|
|
763
|
+
|
|
764
|
+
return [...pluginPool, ...additional];
|
|
524
765
|
}
|
|
525
766
|
|
|
526
767
|
/**
|
|
527
768
|
* Creates the agent configuration object.
|
|
528
769
|
*
|
|
529
|
-
* @param
|
|
770
|
+
* @param signer - The signer instance
|
|
530
771
|
* @param llm - The language model instance
|
|
531
772
|
* @param allPlugins - Array of plugins to use
|
|
532
773
|
* @returns Configuration object for creating the agent
|
|
533
774
|
*/
|
|
534
775
|
private createAgentConfig(
|
|
535
|
-
|
|
776
|
+
signer: ServerSigner,
|
|
536
777
|
llm: ChatOpenAI | ChatAnthropic,
|
|
537
778
|
allPlugins: BasePlugin[]
|
|
538
779
|
): Parameters<typeof createAgent>[0] {
|
|
@@ -550,7 +791,7 @@ export class ConversationalAgent {
|
|
|
550
791
|
|
|
551
792
|
return {
|
|
552
793
|
framework: 'langchain',
|
|
553
|
-
signer
|
|
794
|
+
signer,
|
|
554
795
|
execution: {
|
|
555
796
|
mode: operationalMode === 'autonomous' ? 'direct' : 'bytes',
|
|
556
797
|
operationalMode: operationalMode,
|
|
@@ -820,7 +1061,7 @@ export class ConversationalAgent {
|
|
|
820
1061
|
}
|
|
821
1062
|
if (typeof response === 'string') {
|
|
822
1063
|
const match = response.match(
|
|
823
|
-
/transaction[\s\w]*ID[\s:"]*([0-9a-fA-F
|
|
1064
|
+
/transaction[\s\w]*ID[\s:"]*([0-9a-fA-F@._-]+)/i
|
|
824
1065
|
);
|
|
825
1066
|
return match ? match[1] : undefined;
|
|
826
1067
|
}
|
|
@@ -902,6 +1143,38 @@ export class ConversationalAgent {
|
|
|
902
1143
|
}
|
|
903
1144
|
}
|
|
904
1145
|
|
|
1146
|
+
/**
|
|
1147
|
+
* Switch operational mode
|
|
1148
|
+
*/
|
|
1149
|
+
switchMode(mode?: AgentOperationalMode): void {
|
|
1150
|
+
if (this.agent?.switchMode) {
|
|
1151
|
+
this.agent.switchMode(mode || 'autonomous');
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Get usage statistics
|
|
1157
|
+
*/
|
|
1158
|
+
getUsageStats(): unknown {
|
|
1159
|
+
return this.agent?.getUsageStats?.() ?? {};
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Clear usage statistics
|
|
1164
|
+
*/
|
|
1165
|
+
clearUsageStats(): void {
|
|
1166
|
+
if (this.agent?.clearUsageStats) {
|
|
1167
|
+
this.agent.clearUsageStats();
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* Shutdown the agent
|
|
1173
|
+
*/
|
|
1174
|
+
shutdown(): Promise<void> {
|
|
1175
|
+
return this.agent?.shutdown?.() ?? Promise.resolve();
|
|
1176
|
+
}
|
|
1177
|
+
|
|
905
1178
|
private extractResponseText(response: unknown): string {
|
|
906
1179
|
if (typeof response === 'string') {
|
|
907
1180
|
return response;
|
|
@@ -6,6 +6,13 @@ import {
|
|
|
6
6
|
wrapToolWithFormValidation,
|
|
7
7
|
} from '../langchain/form-validating-tool-wrapper';
|
|
8
8
|
import { FormGenerator } from '../forms/form-generator';
|
|
9
|
+
import {
|
|
10
|
+
fieldGuidanceRegistry,
|
|
11
|
+
} from '../forms/field-guidance-registry';
|
|
12
|
+
import type {
|
|
13
|
+
ToolFieldConfiguration as FG_ToolFieldConfiguration,
|
|
14
|
+
FieldGuidanceProvider as FG_FieldGuidanceProvider,
|
|
15
|
+
} from '../forms/field-guidance-registry';
|
|
9
16
|
import { isFormValidatable } from '@hashgraphonline/standards-agent-kit';
|
|
10
17
|
|
|
11
18
|
/**
|
|
@@ -40,6 +47,8 @@ export interface ToolMetadata {
|
|
|
40
47
|
dependencies: string[];
|
|
41
48
|
schema: unknown;
|
|
42
49
|
entityResolutionPreferences?: EntityResolutionPreferences;
|
|
50
|
+
fieldGuidance?: FG_ToolFieldConfiguration;
|
|
51
|
+
fieldGuidanceProvider?: FG_FieldGuidanceProvider;
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
/**
|
|
@@ -50,6 +59,12 @@ export interface ToolRegistryEntry {
|
|
|
50
59
|
metadata: ToolMetadata;
|
|
51
60
|
wrapper?: FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>> | undefined;
|
|
52
61
|
originalTool: StructuredTool;
|
|
62
|
+
options?: {
|
|
63
|
+
priority?: ToolCapabilities['priority'];
|
|
64
|
+
capability?: string;
|
|
65
|
+
enabled?: boolean;
|
|
66
|
+
namespace?: string;
|
|
67
|
+
};
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
/**
|
|
@@ -188,9 +203,30 @@ export class ToolRegistry {
|
|
|
188
203
|
metadata,
|
|
189
204
|
wrapper,
|
|
190
205
|
originalTool: tool,
|
|
206
|
+
options: {
|
|
207
|
+
priority: capabilities.priority,
|
|
208
|
+
capability: 'basic', // Default capability
|
|
209
|
+
enabled: true, // All tools are enabled by default
|
|
210
|
+
namespace: metadata.category,
|
|
211
|
+
},
|
|
191
212
|
};
|
|
192
213
|
|
|
193
214
|
this.tools.set(tool.name, entry);
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
const metaFG = metadata.fieldGuidance as FG_ToolFieldConfiguration | undefined;
|
|
218
|
+
if (metaFG) {
|
|
219
|
+
fieldGuidanceRegistry.registerToolConfiguration(metaFG);
|
|
220
|
+
}
|
|
221
|
+
const provider = metadata.fieldGuidanceProvider as FG_FieldGuidanceProvider | undefined;
|
|
222
|
+
if (provider) {
|
|
223
|
+
const pattern = metaFG?.toolPattern ?? tool.name;
|
|
224
|
+
fieldGuidanceRegistry.registerToolProvider(pattern, provider, {
|
|
225
|
+
id: `${tool.name}:field-guidance-provider`,
|
|
226
|
+
priority: 0,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
} catch {}
|
|
194
230
|
}
|
|
195
231
|
|
|
196
232
|
/**
|
|
@@ -279,6 +315,55 @@ export class ToolRegistry {
|
|
|
279
315
|
return Array.from(this.tools.keys());
|
|
280
316
|
}
|
|
281
317
|
|
|
318
|
+
/**
|
|
319
|
+
* Get tools by priority
|
|
320
|
+
*/
|
|
321
|
+
getToolsByPriority(priority: ToolCapabilities['priority']): ToolRegistryEntry[] {
|
|
322
|
+
return this.getToolsByCapability('priority', priority);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Get enabled tools (all tools are considered enabled by default)
|
|
327
|
+
*/
|
|
328
|
+
getEnabledTools(): ToolRegistryEntry[] {
|
|
329
|
+
return this.getAllRegistryEntries();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Get tools by namespace/category
|
|
334
|
+
*/
|
|
335
|
+
getToolsByNamespace(namespace?: string): ToolRegistryEntry[] {
|
|
336
|
+
if (!namespace) {
|
|
337
|
+
return this.getAllRegistryEntries();
|
|
338
|
+
}
|
|
339
|
+
return this.getToolsByQuery({ category: namespace as ToolMetadata['category'] });
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Check if registry has capability
|
|
344
|
+
*/
|
|
345
|
+
hasCapability(capability: keyof ToolCapabilities): boolean {
|
|
346
|
+
for (const entry of this.tools.values()) {
|
|
347
|
+
if (entry.metadata.capabilities[capability]) {
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Update tool options (metadata)
|
|
356
|
+
*/
|
|
357
|
+
updateToolOptions(name: string, options: Partial<ToolMetadata>): boolean {
|
|
358
|
+
const entry = this.tools.get(name);
|
|
359
|
+
if (!entry) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
entry.metadata = { ...entry.metadata, ...options };
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
|
|
282
367
|
/**
|
|
283
368
|
* Check if a tool is registered
|
|
284
369
|
*/
|