@hashgraphonline/conversational-agent 0.2.211 → 0.2.212

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.
Files changed (90) hide show
  1. package/cli/dist/CLIApp.d.ts +11 -0
  2. package/cli/dist/CLIApp.d.ts.map +1 -0
  3. package/cli/dist/CLIApp.js +128 -0
  4. package/cli/dist/CLIApp.js.map +1 -0
  5. package/cli/dist/LocalConversationalAgent.d.ts +37 -0
  6. package/cli/dist/LocalConversationalAgent.js +58 -0
  7. package/cli/dist/app.d.ts +18 -0
  8. package/cli/dist/app.d.ts.map +1 -0
  9. package/cli/dist/app.js +14 -0
  10. package/cli/dist/app.js.map +1 -0
  11. package/cli/dist/cli.d.ts +3 -0
  12. package/cli/dist/cli.d.ts.map +1 -0
  13. package/cli/dist/cli.js +87 -0
  14. package/cli/dist/cli.js.map +1 -0
  15. package/cli/dist/components/AppContainer.d.ts +16 -0
  16. package/cli/dist/components/AppContainer.js +24 -0
  17. package/cli/dist/components/AppScreens.d.ts +2 -0
  18. package/cli/dist/components/AppScreens.js +259 -0
  19. package/cli/dist/components/ChatScreen.d.ts +21 -0
  20. package/cli/dist/components/ChatScreen.d.ts.map +1 -0
  21. package/cli/dist/components/ChatScreen.js +40 -0
  22. package/cli/dist/components/ChatScreen.js.map +1 -0
  23. package/cli/dist/components/DebugLoadingScreen.d.ts +5 -0
  24. package/cli/dist/components/DebugLoadingScreen.js +31 -0
  25. package/cli/dist/components/LoadingScreen.d.ts +3 -0
  26. package/cli/dist/components/LoadingScreen.d.ts.map +1 -0
  27. package/cli/dist/components/LoadingScreen.js +17 -0
  28. package/cli/dist/components/LoadingScreen.js.map +1 -0
  29. package/cli/dist/components/LoadingScreenDebug.d.ts +5 -0
  30. package/cli/dist/components/LoadingScreenDebug.js +27 -0
  31. package/cli/dist/components/MCPConfigScreen.d.ts +28 -0
  32. package/cli/dist/components/MCPConfigScreen.d.ts.map +1 -0
  33. package/cli/dist/components/MCPConfigScreen.js +186 -0
  34. package/cli/dist/components/MCPConfigScreen.js.map +1 -0
  35. package/cli/dist/components/ScreenRouter.d.ts +13 -0
  36. package/cli/dist/components/ScreenRouter.d.ts.map +1 -0
  37. package/cli/dist/components/ScreenRouter.js +23 -0
  38. package/cli/dist/components/ScreenRouter.js.map +1 -0
  39. package/cli/dist/components/SetupScreen.d.ts +16 -0
  40. package/cli/dist/components/SetupScreen.d.ts.map +1 -0
  41. package/cli/dist/components/SetupScreen.js +67 -0
  42. package/cli/dist/components/SetupScreen.js.map +1 -0
  43. package/cli/dist/components/SingleLoadingScreen.d.ts +5 -0
  44. package/cli/dist/components/SingleLoadingScreen.js +27 -0
  45. package/cli/dist/components/StatusBadge.d.ts +10 -0
  46. package/cli/dist/components/StatusBadge.d.ts.map +1 -0
  47. package/cli/dist/components/StatusBadge.js +24 -0
  48. package/cli/dist/components/StatusBadge.js.map +1 -0
  49. package/cli/dist/components/TerminalWindow.d.ts +9 -0
  50. package/cli/dist/components/TerminalWindow.d.ts.map +1 -0
  51. package/cli/dist/components/TerminalWindow.js +19 -0
  52. package/cli/dist/components/TerminalWindow.js.map +1 -0
  53. package/cli/dist/components/WelcomeScreen.d.ts +12 -0
  54. package/cli/dist/components/WelcomeScreen.d.ts.map +1 -0
  55. package/cli/dist/components/WelcomeScreen.js +47 -0
  56. package/cli/dist/components/WelcomeScreen.js.map +1 -0
  57. package/cli/dist/context/AppContext.d.ts +68 -0
  58. package/cli/dist/context/AppContext.js +363 -0
  59. package/cli/dist/headless-runner.d.ts +17 -0
  60. package/cli/dist/headless-runner.d.ts.map +1 -0
  61. package/cli/dist/headless-runner.js +128 -0
  62. package/cli/dist/headless-runner.js.map +1 -0
  63. package/cli/dist/hooks/useInitializeAgent.d.ts +19 -0
  64. package/cli/dist/hooks/useInitializeAgent.d.ts.map +1 -0
  65. package/cli/dist/hooks/useInitializeAgent.js +29 -0
  66. package/cli/dist/hooks/useInitializeAgent.js.map +1 -0
  67. package/cli/dist/hooks/useStableState.d.ts +38 -0
  68. package/cli/dist/hooks/useStableState.d.ts.map +1 -0
  69. package/cli/dist/hooks/useStableState.js +69 -0
  70. package/cli/dist/hooks/useStableState.js.map +1 -0
  71. package/cli/dist/managers/AgentManager.d.ts +58 -0
  72. package/cli/dist/managers/AgentManager.d.ts.map +1 -0
  73. package/cli/dist/managers/AgentManager.js +121 -0
  74. package/cli/dist/managers/AgentManager.js.map +1 -0
  75. package/cli/dist/managers/ConfigManager.d.ts +54 -0
  76. package/cli/dist/managers/ConfigManager.d.ts.map +1 -0
  77. package/cli/dist/managers/ConfigManager.js +188 -0
  78. package/cli/dist/managers/ConfigManager.js.map +1 -0
  79. package/cli/dist/types.d.ts +52 -0
  80. package/cli/dist/types.d.ts.map +1 -0
  81. package/cli/dist/types.js +34 -0
  82. package/cli/dist/types.js.map +1 -0
  83. package/dist/esm/index10.js +1 -1
  84. package/dist/esm/index21.js +1 -1
  85. package/dist/esm/index46.js +6 -26
  86. package/dist/esm/index46.js.map +1 -1
  87. package/dist/esm/index47.js +26 -6
  88. package/dist/esm/index47.js.map +1 -1
  89. package/package.json +25 -33
  90. package/cli/readme.md +0 -181
@@ -0,0 +1,363 @@
1
+ import React, { createContext, useContext, useReducer, useCallback, useRef, useEffect } from 'react';
2
+ import { ConversationalAgent, MCPServers } from '@hashgraphonline/conversational-agent';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ const AppContext = createContext(null);
6
+ /**
7
+ * Get MCP config file path
8
+ */
9
+ const getMCPConfigPath = () => {
10
+ const projectRoot = process.env['CONVERSATIONAL_AGENT_ROOT'] || path.resolve('./../../');
11
+ return path.join(projectRoot, 'mcp-config.json');
12
+ };
13
+ /**
14
+ * Load MCP configuration from file
15
+ */
16
+ const loadMCPConfig = () => {
17
+ const configPath = getMCPConfigPath();
18
+ try {
19
+ if (fs.existsSync(configPath)) {
20
+ const configContent = fs.readFileSync(configPath, 'utf-8');
21
+ const config = JSON.parse(configContent);
22
+ return Object.values(config.mcpServers || {});
23
+ }
24
+ }
25
+ catch (err) {
26
+ console.error('Failed to load MCP config:', err);
27
+ }
28
+ const defaultServers = [MCPServers.filesystem(process.cwd())];
29
+ saveMCPConfig(defaultServers);
30
+ return defaultServers;
31
+ };
32
+ /**
33
+ * Save MCP configuration to file
34
+ */
35
+ const saveMCPConfig = (servers) => {
36
+ const configPath = getMCPConfigPath();
37
+ try {
38
+ const mcpServers = {};
39
+ servers.forEach(server => {
40
+ mcpServers[server.name] = server;
41
+ });
42
+ const config = { mcpServers };
43
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
44
+ }
45
+ catch (err) {
46
+ console.error('Failed to save MCP config:', err);
47
+ }
48
+ };
49
+ /**
50
+ * Load config from .env file
51
+ */
52
+ const loadConfigFromEnv = () => {
53
+ const projectRoot = process.env['CONVERSATIONAL_AGENT_ROOT'] || path.resolve('./../../');
54
+ const envPath = path.join(projectRoot, '.env');
55
+ try {
56
+ if (fs.existsSync(envPath)) {
57
+ const envContent = fs.readFileSync(envPath, 'utf-8');
58
+ const envVars = {};
59
+ envContent.split('\n').forEach(line => {
60
+ const trimmedLine = line.trim();
61
+ if (trimmedLine && !trimmedLine.startsWith('#')) {
62
+ const [key, ...valueParts] = trimmedLine.split('=');
63
+ if (key && valueParts.length > 0) {
64
+ envVars[key] = valueParts.join('=');
65
+ }
66
+ }
67
+ });
68
+ return {
69
+ accountId: envVars['HEDERA_ACCOUNT_ID'] || '',
70
+ privateKey: envVars['HEDERA_PRIVATE_KEY'] || '',
71
+ network: envVars['HEDERA_NETWORK'] || 'testnet',
72
+ openAIApiKey: envVars['OPENAI_API_KEY'] || '',
73
+ mcpServers: envVars['MCP_SERVERS'] ? JSON.parse(envVars['MCP_SERVERS']) : [],
74
+ };
75
+ }
76
+ }
77
+ catch (err) { }
78
+ return {
79
+ accountId: '',
80
+ privateKey: '',
81
+ network: 'testnet',
82
+ openAIApiKey: '',
83
+ mcpServers: [],
84
+ };
85
+ };
86
+ /**
87
+ * Save config to .env file
88
+ */
89
+ const saveConfig = (configToSave) => {
90
+ const projectRoot = process.env['CONVERSATIONAL_AGENT_ROOT'] || path.resolve('./../../');
91
+ const envPath = path.join(projectRoot, '.env');
92
+ try {
93
+ let envContent = '';
94
+ if (fs.existsSync(envPath)) {
95
+ envContent = fs.readFileSync(envPath, 'utf-8');
96
+ }
97
+ const updateEnvVar = (key, value) => {
98
+ const regex = new RegExp(`^${key}=.*$`, 'gm');
99
+ if (regex.test(envContent)) {
100
+ envContent = envContent.replace(regex, `${key}=${value}`);
101
+ }
102
+ else {
103
+ envContent += `${envContent ? '\n' : ''}${key}=${value}`;
104
+ }
105
+ };
106
+ updateEnvVar('HEDERA_ACCOUNT_ID', configToSave.accountId);
107
+ updateEnvVar('HEDERA_PRIVATE_KEY', configToSave.privateKey);
108
+ updateEnvVar('HEDERA_NETWORK', configToSave.network);
109
+ updateEnvVar('OPENAI_API_KEY', configToSave.openAIApiKey);
110
+ updateEnvVar('MCP_SERVERS', JSON.stringify(configToSave.mcpServers || []));
111
+ fs.writeFileSync(envPath, envContent);
112
+ }
113
+ catch (err) { }
114
+ };
115
+ const appReducer = (state, action) => {
116
+ switch (action.type) {
117
+ case 'SET_SCREEN':
118
+ return { ...state, screen: action.payload };
119
+ case 'SET_AGENT':
120
+ return { ...state, agent: action.payload };
121
+ case 'SET_MESSAGES':
122
+ return { ...state, messages: action.payload };
123
+ case 'ADD_MESSAGES':
124
+ return { ...state, messages: [...state.messages, ...action.payload] };
125
+ case 'SET_INPUT':
126
+ return { ...state, input: action.payload };
127
+ case 'SET_LOADING':
128
+ return { ...state, isLoading: action.payload };
129
+ case 'SET_ERROR':
130
+ return { ...state, error: action.payload };
131
+ case 'SET_CONFIG':
132
+ return { ...state, config: action.payload };
133
+ case 'UPDATE_CONFIG_FIELD':
134
+ return {
135
+ ...state,
136
+ config: { ...state.config, [action.payload.field]: action.payload.value }
137
+ };
138
+ case 'SET_MCP_CONFIG':
139
+ return { ...state, mcpConfig: { ...state.mcpConfig, ...action.payload } };
140
+ case 'SET_EDITING_FILESYSTEM_PATH':
141
+ return { ...state, editingFilesystemPath: action.payload };
142
+ case 'SET_CURRENT_FIELD':
143
+ return { ...state, currentField: action.payload };
144
+ case 'SET_LOGS':
145
+ return { ...state, logs: action.payload };
146
+ default:
147
+ return state;
148
+ }
149
+ };
150
+ export const AppProvider = ({ children, accountId, privateKey, network = 'testnet', openAIApiKey, }) => {
151
+ const agentRef = useRef(null);
152
+ const initializingRef = useRef(false);
153
+ const autoInitialized = useRef(false);
154
+ const getInitialState = () => {
155
+ const envConfig = loadConfigFromEnv();
156
+ const loadedServers = loadMCPConfig();
157
+ const filesystemServer = loadedServers.find(s => s.name === 'filesystem');
158
+ const customServers = loadedServers.filter(s => s.name !== 'filesystem');
159
+ return {
160
+ screen: 'welcome',
161
+ agent: null,
162
+ messages: [],
163
+ input: '',
164
+ isLoading: false,
165
+ error: null,
166
+ config: {
167
+ accountId: accountId || envConfig.accountId,
168
+ privateKey: privateKey || envConfig.privateKey,
169
+ network: network || envConfig.network,
170
+ openAIApiKey: openAIApiKey || envConfig.openAIApiKey,
171
+ mcpServers: envConfig.mcpServers || [],
172
+ },
173
+ mcpConfig: {
174
+ enableFilesystem: !!filesystemServer,
175
+ filesystemPath: filesystemServer ? filesystemServer.args[2] || process.cwd() : process.cwd(),
176
+ customServers,
177
+ addingCustom: false,
178
+ newServerName: '',
179
+ newServerCommand: '',
180
+ newServerArgs: '',
181
+ newServerEnv: '',
182
+ currentField: 0,
183
+ },
184
+ editingFilesystemPath: false,
185
+ currentField: 0,
186
+ logs: [],
187
+ };
188
+ };
189
+ const [state, dispatch] = useReducer(appReducer, getInitialState());
190
+ const initializeAgent = useCallback(async () => {
191
+ if (agentRef.current) {
192
+ dispatch({ type: 'SET_AGENT', payload: agentRef.current });
193
+ dispatch({ type: 'SET_SCREEN', payload: 'chat' });
194
+ return;
195
+ }
196
+ if (initializingRef.current) {
197
+ return;
198
+ }
199
+ initializingRef.current = true;
200
+ dispatch({ type: 'SET_LOADING', payload: true });
201
+ dispatch({ type: 'SET_ERROR', payload: null });
202
+ try {
203
+ saveConfig(state.config);
204
+ const mcpServers = [];
205
+ if (state.mcpConfig.enableFilesystem && state.mcpConfig.filesystemPath) {
206
+ mcpServers.push(MCPServers.filesystem(state.mcpConfig.filesystemPath));
207
+ }
208
+ mcpServers.push(...state.mcpConfig.customServers);
209
+ const agentConfig = {
210
+ accountId: state.config.accountId,
211
+ privateKey: state.config.privateKey,
212
+ network: state.config.network,
213
+ openAIApiKey: state.config.openAIApiKey,
214
+ openAIModelName: 'gpt-4o-mini',
215
+ verbose: false,
216
+ disableLogging: true,
217
+ ...(mcpServers.length > 0 && { mcpServers }),
218
+ };
219
+ const conversationalAgent = new ConversationalAgent(agentConfig);
220
+ await conversationalAgent.initialize();
221
+ agentRef.current = conversationalAgent;
222
+ dispatch({ type: 'SET_AGENT', payload: conversationalAgent });
223
+ dispatch({ type: 'SET_SCREEN', payload: 'chat' });
224
+ const welcomeMessages = [
225
+ {
226
+ role: 'system',
227
+ content: `Connected to Hedera ${state.config.network}`,
228
+ timestamp: new Date(),
229
+ },
230
+ ];
231
+ if (mcpServers.length > 0) {
232
+ welcomeMessages.push({
233
+ role: 'system',
234
+ content: `MCP servers enabled: ${mcpServers.map(s => s.name).join(', ')}`,
235
+ timestamp: new Date(),
236
+ });
237
+ }
238
+ welcomeMessages.push({
239
+ role: 'assistant',
240
+ content: mcpServers.length > 0
241
+ ? "Hello! I'm your Hashgraph Consensus Standards Conversational Agent with extended MCP capabilities. I can help you manage HCS-10 agent registrations, HCS-11 profiles, send messages through HCS standards, interact with the Hedera network, and use external tools for file operations and more. How can I assist you today?"
242
+ : "Hello! I'm your Hashgraph Consensus Standards Conversational Agent. I can help you manage HCS-10 agent registrations, HCS-11 profiles, send messages through HCS standards, and interact with the Hedera network. How can I assist you today?",
243
+ timestamp: new Date(),
244
+ });
245
+ dispatch({ type: 'SET_MESSAGES', payload: welcomeMessages });
246
+ }
247
+ catch (err) {
248
+ dispatch({
249
+ type: 'SET_ERROR',
250
+ payload: err instanceof Error ? err.message : 'Failed to initialize agent',
251
+ });
252
+ dispatch({ type: 'SET_SCREEN', payload: 'setup' });
253
+ }
254
+ finally {
255
+ dispatch({ type: 'SET_LOADING', payload: false });
256
+ initializingRef.current = false;
257
+ }
258
+ }, [state.config, state.mcpConfig]);
259
+ const sendMessage = useCallback(async (message) => {
260
+ const currentAgent = agentRef.current || state.agent;
261
+ if (!currentAgent || !message.trim())
262
+ return;
263
+ const userMessage = {
264
+ role: 'user',
265
+ content: message,
266
+ timestamp: new Date(),
267
+ };
268
+ dispatch({ type: 'ADD_MESSAGES', payload: [userMessage] });
269
+ dispatch({ type: 'SET_INPUT', payload: '' });
270
+ dispatch({ type: 'SET_LOADING', payload: true });
271
+ try {
272
+ const chatHistory = state.messages
273
+ .filter(m => m.role !== 'system')
274
+ .map(m => ({
275
+ type: m.role === 'user' ? 'human' : 'ai',
276
+ content: m.content,
277
+ }));
278
+ const response = await currentAgent.processMessage(message, chatHistory);
279
+ const assistantMessage = {
280
+ role: 'assistant',
281
+ content: response.message || response.output || response.error || 'No response received',
282
+ timestamp: new Date(),
283
+ };
284
+ const newMessages = [assistantMessage];
285
+ if (response.transactionId) {
286
+ newMessages.push({
287
+ role: 'system',
288
+ content: `Transaction ID: ${response.transactionId}`,
289
+ timestamp: new Date(),
290
+ });
291
+ }
292
+ if (response.scheduleId) {
293
+ newMessages.push({
294
+ role: 'system',
295
+ content: `Schedule ID: ${response.scheduleId}`,
296
+ timestamp: new Date(),
297
+ });
298
+ }
299
+ if (response.notes && response.notes.length > 0) {
300
+ response.notes.forEach((note) => {
301
+ newMessages.push({
302
+ role: 'system',
303
+ content: note,
304
+ timestamp: new Date(),
305
+ });
306
+ });
307
+ }
308
+ dispatch({ type: 'ADD_MESSAGES', payload: newMessages });
309
+ }
310
+ catch (err) {
311
+ dispatch({
312
+ type: 'ADD_MESSAGES',
313
+ payload: [{
314
+ role: 'system',
315
+ content: `Error: ${err instanceof Error ? err.message : 'Unknown error'}`,
316
+ timestamp: new Date(),
317
+ }],
318
+ });
319
+ }
320
+ finally {
321
+ dispatch({ type: 'SET_LOADING', payload: false });
322
+ }
323
+ }, [state.agent, state.messages]);
324
+ const actions = {
325
+ setScreen: useCallback((screen) => dispatch({ type: 'SET_SCREEN', payload: screen }), []),
326
+ setAgent: useCallback((agent) => dispatch({ type: 'SET_AGENT', payload: agent }), []),
327
+ setMessages: useCallback((messages) => dispatch({ type: 'SET_MESSAGES', payload: messages }), []),
328
+ addMessages: useCallback((messages) => dispatch({ type: 'ADD_MESSAGES', payload: messages }), []),
329
+ setInput: useCallback((input) => dispatch({ type: 'SET_INPUT', payload: input }), []),
330
+ setLoading: useCallback((loading) => dispatch({ type: 'SET_LOADING', payload: loading }), []),
331
+ setError: useCallback((error) => dispatch({ type: 'SET_ERROR', payload: error }), []),
332
+ setConfig: useCallback((config) => dispatch({ type: 'SET_CONFIG', payload: config }), []),
333
+ updateConfigField: useCallback((field, value) => dispatch({ type: 'UPDATE_CONFIG_FIELD', payload: { field, value } }), []),
334
+ setMcpConfig: useCallback((config) => dispatch({ type: 'SET_MCP_CONFIG', payload: config }), []),
335
+ setEditingFilesystemPath: useCallback((editing) => dispatch({ type: 'SET_EDITING_FILESYSTEM_PATH', payload: editing }), []),
336
+ setCurrentField: useCallback((field) => dispatch({ type: 'SET_CURRENT_FIELD', payload: field }), []),
337
+ setLogs: useCallback((logs) => dispatch({ type: 'SET_LOGS', payload: logs }), []),
338
+ initializeAgent,
339
+ sendMessage,
340
+ };
341
+ useEffect(() => {
342
+ const hasRequiredConfig = state.config.accountId &&
343
+ state.config.privateKey &&
344
+ state.config.openAIApiKey;
345
+ if (hasRequiredConfig && !autoInitialized.current && !agentRef.current) {
346
+ autoInitialized.current = true;
347
+ initializeAgent();
348
+ }
349
+ }, [state.config.accountId, state.config.privateKey, state.config.openAIApiKey, initializeAgent]);
350
+ const contextValue = {
351
+ state,
352
+ actions,
353
+ };
354
+ return React.createElement(AppContext.Provider, { value: contextValue }, children);
355
+ };
356
+ export const useAppContext = () => {
357
+ const context = useContext(AppContext);
358
+ if (!context) {
359
+ throw new Error('useAppContext must be used within an AppProvider');
360
+ }
361
+ return context;
362
+ };
363
+ export { saveMCPConfig, getMCPConfigPath };
@@ -0,0 +1,17 @@
1
+ import { type Network } from './types';
2
+ export interface HeadlessRunOptions {
3
+ accountId?: string;
4
+ privateKey?: string;
5
+ network?: Network;
6
+ openAIApiKey?: string;
7
+ command?: string;
8
+ }
9
+ export interface HeadlessRunResult {
10
+ exitCode: number;
11
+ stdout: string;
12
+ }
13
+ /**
14
+ * Executes the conversational agent in a non-interactive mode and returns formatted output.
15
+ */
16
+ export declare function runHeadless(options: HeadlessRunOptions): Promise<HeadlessRunResult>;
17
+ //# sourceMappingURL=headless-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headless-runner.d.ts","sourceRoot":"","sources":["../src/headless-runner.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6C,KAAK,OAAO,EAAC,MAAM,SAAS,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CACf;AA4DD;;GAEG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,kBAAkB,GACzB,OAAO,CAAC,iBAAiB,CAAC,CA+E5B"}
@@ -0,0 +1,128 @@
1
+ import { ConfigManager } from './managers/ConfigManager';
2
+ import { AgentManager } from './managers/AgentManager';
3
+ const newline = '\n';
4
+ function buildMcpConfig(servers) {
5
+ const filesystemServer = servers.find(server => server.name === 'filesystem');
6
+ const customServers = servers.filter(server => server.name !== 'filesystem');
7
+ return {
8
+ enableFilesystem: Boolean(filesystemServer),
9
+ filesystemPath: filesystemServer?.args?.[2] ?? process.cwd(),
10
+ customServers,
11
+ };
12
+ }
13
+ function formatMessages(messages) {
14
+ return messages.map(message => `[${message.role}] ${message.content}`);
15
+ }
16
+ function formatCommand(command) {
17
+ return command ? `[command] ${command}` : '';
18
+ }
19
+ function formatResponse(response) {
20
+ const lines = [];
21
+ if (response.message) {
22
+ lines.push(`[assistant] ${response.message}`);
23
+ }
24
+ else if (response.output) {
25
+ lines.push(`[assistant] ${response.output}`);
26
+ }
27
+ if (response.error) {
28
+ lines.push(`[error] ${response.error}`);
29
+ }
30
+ if (response.transactionId) {
31
+ lines.push(`[transaction] ${response.transactionId}`);
32
+ }
33
+ if (response.scheduleId) {
34
+ lines.push(`[schedule] ${response.scheduleId}`);
35
+ }
36
+ if (response.notes?.length) {
37
+ response.notes.forEach(note => {
38
+ lines.push(`[note] ${note}`);
39
+ });
40
+ }
41
+ return lines;
42
+ }
43
+ function ensureTrailingNewline(text) {
44
+ if (!text) {
45
+ return text;
46
+ }
47
+ return text.endsWith(newline) ? text : `${text}${newline}`;
48
+ }
49
+ /**
50
+ * Executes the conversational agent in a non-interactive mode and returns formatted output.
51
+ */
52
+ export async function runHeadless(options) {
53
+ const agentManager = AgentManager.getInstance();
54
+ const configManager = ConfigManager.getInstance();
55
+ configManager.resetCache();
56
+ const overrides = {};
57
+ if (options.accountId) {
58
+ overrides.accountId = options.accountId;
59
+ }
60
+ if (options.privateKey) {
61
+ overrides.privateKey = options.privateKey;
62
+ }
63
+ if (options.network) {
64
+ overrides.network = options.network;
65
+ }
66
+ if (options.openAIApiKey) {
67
+ overrides.openAIApiKey = options.openAIApiKey;
68
+ }
69
+ const baseConfig = configManager.getConfig(overrides);
70
+ const effectivePrivateKey = options.privateKey ||
71
+ baseConfig.privateKey ||
72
+ process.env.HEDERA_OPERATOR_KEY ||
73
+ '';
74
+ const effectiveAccountId = options.accountId || baseConfig.accountId;
75
+ const effectiveNetwork = options.network ?? baseConfig.network;
76
+ const effectiveOpenAiKey = options.openAIApiKey ||
77
+ baseConfig.openAIApiKey ||
78
+ process.env.OPENAI_API_KEY ||
79
+ '';
80
+ if (!effectiveAccountId || !effectivePrivateKey) {
81
+ const message = ensureTrailingNewline('Missing account ID or private key for headless execution.');
82
+ return { exitCode: 1, stdout: message };
83
+ }
84
+ const mcpServers = configManager.getMCPServers();
85
+ const config = {
86
+ accountId: effectiveAccountId,
87
+ privateKey: effectivePrivateKey,
88
+ network: effectiveNetwork,
89
+ openAIApiKey: effectiveOpenAiKey,
90
+ mcpServers,
91
+ };
92
+ const command = options.command?.trim() ?? '';
93
+ const outputLines = [];
94
+ let exitCode = 0;
95
+ agentManager.reset();
96
+ try {
97
+ const { welcomeMessages } = await agentManager.initialize(config, buildMcpConfig(mcpServers));
98
+ outputLines.push(...formatMessages(welcomeMessages));
99
+ if (command) {
100
+ outputLines.push(formatCommand(command));
101
+ try {
102
+ const response = await agentManager.sendMessage(command, []);
103
+ const responseLines = formatResponse(response);
104
+ outputLines.push(...responseLines);
105
+ if (response.error) {
106
+ exitCode = 1;
107
+ }
108
+ }
109
+ catch (error) {
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ outputLines.push(`[error] ${message}`);
112
+ exitCode = 1;
113
+ }
114
+ }
115
+ }
116
+ catch (error) {
117
+ const message = error instanceof Error ? error.message : String(error);
118
+ outputLines.push(`[error] ${message}`);
119
+ exitCode = 1;
120
+ }
121
+ finally {
122
+ agentManager.reset();
123
+ }
124
+ const filteredLines = outputLines.filter(line => Boolean(line));
125
+ const stdout = ensureTrailingNewline(filteredLines.join(newline));
126
+ return { exitCode, stdout };
127
+ }
128
+ //# sourceMappingURL=headless-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headless-runner.js","sourceRoot":"","sources":["../src/headless-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { ConfigManager } from '../managers/ConfigManager';
2
+ import { AgentManager } from '../managers/AgentManager';
3
+ import { type Config, type Screen, type Message, type MCPServerConfig } from '../types';
4
+ interface InitializeAgentProps {
5
+ configManager: ConfigManager;
6
+ agentManager: AgentManager;
7
+ actions: {
8
+ setScreen: (screen: Screen) => void;
9
+ setMessages: (messages: Message[]) => void;
10
+ setError: (error: string | null) => void;
11
+ };
12
+ }
13
+ export declare const useInitializeAgent: ({ configManager, agentManager, actions, }: InitializeAgentProps) => (currentConfig: Config, mcpConfig: {
14
+ enableFilesystem: boolean;
15
+ filesystemPath: string;
16
+ customServers: MCPServerConfig[];
17
+ }) => Promise<void>;
18
+ export {};
19
+ //# sourceMappingURL=useInitializeAgent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInitializeAgent.d.ts","sourceRoot":"","sources":["../../src/hooks/useInitializeAgent.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAC,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAC,MAAM,UAAU,CAAC;AAEtF,UAAU,oBAAoB;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE;QACR,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACpC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;KACzC,CAAC;CACF;AAED,eAAO,MAAM,kBAAkB,GAAI,2CAIhC,oBAAoB,qBAKL,MAAM,aACV;IACV,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,eAAe,EAAE,CAAC;CACjC,kBAwCH,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { useRef, useCallback } from 'react';
2
+ export const useInitializeAgent = ({ configManager, agentManager, actions, }) => {
3
+ const initializingRef = useRef(false);
4
+ const initializeAgent = useCallback(async (currentConfig, mcpConfig) => {
5
+ if (agentManager.isInitialized() ||
6
+ agentManager.isInitializing() ||
7
+ initializingRef.current) {
8
+ return;
9
+ }
10
+ initializingRef.current = true;
11
+ actions.setScreen('loading');
12
+ try {
13
+ await configManager.saveConfig(currentConfig);
14
+ const { welcomeMessages } = await agentManager.initialize({ ...currentConfig, mcpServers: configManager.getMCPServers() }, mcpConfig);
15
+ actions.setMessages(welcomeMessages);
16
+ await new Promise(resolve => setTimeout(resolve, 100));
17
+ actions.setScreen('chat');
18
+ }
19
+ catch (err) {
20
+ actions.setError(err instanceof Error ? err.message : 'Failed to initialize agent');
21
+ actions.setScreen('setup');
22
+ }
23
+ finally {
24
+ initializingRef.current = false;
25
+ }
26
+ }, [configManager, agentManager, actions]);
27
+ return initializeAgent;
28
+ };
29
+ //# sourceMappingURL=useInitializeAgent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInitializeAgent.js","sourceRoot":"","sources":["../../src/hooks/useInitializeAgent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,OAAO,CAAC;AAe1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAClC,aAAa,EACb,YAAY,EACZ,OAAO,GACe,EAAE,EAAE;IAC1B,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAEtC,MAAM,eAAe,GAAG,WAAW,CAClC,KAAK,EACJ,aAAqB,EACrB,SAIC,EACA,EAAE;QACH,IACC,YAAY,CAAC,aAAa,EAAE;YAC5B,YAAY,CAAC,cAAc,EAAE;YAC7B,eAAe,CAAC,OAAO,EACtB,CAAC;YACF,OAAO;QACR,CAAC;QAED,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC;QAE/B,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE7B,IAAI,CAAC;YACJ,MAAM,aAAa,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;YAE9C,MAAM,EAAC,eAAe,EAAC,GAAG,MAAM,YAAY,CAAC,UAAU,CACtD,EAAC,GAAG,aAAa,EAAE,UAAU,EAAE,aAAa,CAAC,aAAa,EAAE,EAAC,EAC7D,SAAS,CACT,CAAC;YAEF,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;YAErC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAEvD,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,QAAQ,CACf,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,CACjE,CAAC;YACF,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACV,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC;QACjC,CAAC;IACF,CAAC,EACD,CAAC,aAAa,EAAE,YAAY,EAAE,OAAO,CAAC,CACtC,CAAC;IAEF,OAAO,eAAe,CAAC;AACxB,CAAC,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { type Screen, type Message, type MCPServerConfig } from '../types';
2
+ export interface AppState {
3
+ screen: Screen;
4
+ messages: Message[];
5
+ input: string;
6
+ isLoading: boolean;
7
+ error: string | null;
8
+ mcpConfig: {
9
+ enableFilesystem: boolean;
10
+ filesystemPath: string;
11
+ customServers: MCPServerConfig[];
12
+ addingCustom: boolean;
13
+ newServerName: string;
14
+ newServerCommand: string;
15
+ newServerArgs: string;
16
+ newServerEnv: string;
17
+ currentField: number;
18
+ };
19
+ editingFilesystemPath: boolean;
20
+ currentField: number;
21
+ logs: string[];
22
+ }
23
+ export declare const useStableState: (initialMcpServers: MCPServerConfig[]) => {
24
+ state: AppState;
25
+ actions: {
26
+ setScreen: (screen: Screen) => void;
27
+ setMessages: (messages: Message[]) => void;
28
+ addMessages: (messages: Message[]) => void;
29
+ setInput: (input: string) => void;
30
+ setLoading: (loading: boolean) => void;
31
+ setError: (error: string | null) => void;
32
+ setMcpConfig: (config: Partial<AppState["mcpConfig"]>) => void;
33
+ setEditingFilesystemPath: (editing: boolean) => void;
34
+ setCurrentField: (field: number) => void;
35
+ setLogs: (logs: string[]) => void;
36
+ };
37
+ };
38
+ //# sourceMappingURL=useStableState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStableState.d.ts","sourceRoot":"","sources":["../../src/hooks/useStableState.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAC,MAAM,UAAU,CAAC;AAEzE,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE;QACT,gBAAgB,EAAE,OAAO,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,eAAe,EAAE,CAAC;QACjC,YAAY,EAAE,OAAO,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,qBAAqB,EAAE,OAAO,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAyCD,eAAO,MAAM,cAAc,GAAI,mBAAmB,eAAe,EAAE;;;4BA+B3C,MAAM;gCACF,OAAO,EAAE;gCACT,OAAO,EAAE;0BACf,MAAM;8BACF,OAAO;0BACX,MAAM,GAAG,IAAI;+BACR,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;4CACjB,OAAO;iCAClB,MAAM;wBACf,MAAM,EAAE;;CAI3B,CAAC"}