@hashgraphonline/conversational-agent 0.1.214 → 0.1.217

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/cli/dist/CLIApp.d.ts +9 -0
  2. package/cli/dist/CLIApp.js +127 -0
  3. package/cli/dist/LocalConversationalAgent.d.ts +37 -0
  4. package/cli/dist/LocalConversationalAgent.js +58 -0
  5. package/cli/dist/app.d.ts +16 -0
  6. package/cli/dist/app.js +13 -0
  7. package/cli/dist/cli.d.ts +2 -0
  8. package/cli/dist/cli.js +51 -0
  9. package/cli/dist/components/AppContainer.d.ts +16 -0
  10. package/cli/dist/components/AppContainer.js +24 -0
  11. package/cli/dist/components/AppScreens.d.ts +2 -0
  12. package/cli/dist/components/AppScreens.js +259 -0
  13. package/cli/dist/components/ChatScreen.d.ts +15 -0
  14. package/cli/dist/components/ChatScreen.js +39 -0
  15. package/cli/dist/components/DebugLoadingScreen.d.ts +5 -0
  16. package/cli/dist/components/DebugLoadingScreen.js +31 -0
  17. package/cli/dist/components/LoadingScreen.d.ts +2 -0
  18. package/cli/dist/components/LoadingScreen.js +16 -0
  19. package/cli/dist/components/LoadingScreenDebug.d.ts +5 -0
  20. package/cli/dist/components/LoadingScreenDebug.js +27 -0
  21. package/cli/dist/components/MCPConfigScreen.d.ts +28 -0
  22. package/cli/dist/components/MCPConfigScreen.js +168 -0
  23. package/cli/dist/components/ScreenRouter.d.ts +12 -0
  24. package/cli/dist/components/ScreenRouter.js +22 -0
  25. package/cli/dist/components/SetupScreen.d.ts +15 -0
  26. package/cli/dist/components/SetupScreen.js +65 -0
  27. package/cli/dist/components/SingleLoadingScreen.d.ts +5 -0
  28. package/cli/dist/components/SingleLoadingScreen.js +27 -0
  29. package/cli/dist/components/StatusBadge.d.ts +7 -0
  30. package/cli/dist/components/StatusBadge.js +28 -0
  31. package/cli/dist/components/TerminalWindow.d.ts +8 -0
  32. package/cli/dist/components/TerminalWindow.js +24 -0
  33. package/cli/dist/components/WelcomeScreen.d.ts +11 -0
  34. package/cli/dist/components/WelcomeScreen.js +47 -0
  35. package/cli/dist/context/AppContext.d.ts +68 -0
  36. package/cli/dist/context/AppContext.js +363 -0
  37. package/cli/dist/hooks/useInitializeAgent.d.ts +19 -0
  38. package/cli/dist/hooks/useInitializeAgent.js +28 -0
  39. package/cli/dist/hooks/useStableState.d.ts +38 -0
  40. package/cli/dist/hooks/useStableState.js +68 -0
  41. package/cli/dist/managers/AgentManager.d.ts +57 -0
  42. package/cli/dist/managers/AgentManager.js +119 -0
  43. package/cli/dist/managers/ConfigManager.d.ts +53 -0
  44. package/cli/dist/managers/ConfigManager.js +173 -0
  45. package/cli/dist/types.d.ts +31 -0
  46. package/cli/dist/types.js +19 -0
  47. package/dist/cjs/base-agent.d.ts +2 -0
  48. package/dist/cjs/conversational-agent.d.ts +8 -0
  49. package/dist/cjs/core/ToolRegistry.d.ts +130 -0
  50. package/dist/cjs/execution/ExecutionPipeline.d.ts +81 -0
  51. package/dist/cjs/forms/FormEngine.d.ts +121 -0
  52. package/dist/cjs/forms/field-type-registry.d.ts +51 -0
  53. package/dist/cjs/forms/form-generator.d.ts +123 -0
  54. package/dist/cjs/forms/index.d.ts +2 -0
  55. package/dist/cjs/forms/types.d.ts +108 -0
  56. package/dist/cjs/index.cjs +1 -1
  57. package/dist/cjs/index.cjs.map +1 -1
  58. package/dist/cjs/index.d.ts +5 -0
  59. package/dist/cjs/langchain/FormAwareAgentExecutor.d.ts +108 -0
  60. package/dist/cjs/langchain/FormValidatingToolWrapper.d.ts +81 -0
  61. package/dist/cjs/langchain-agent.d.ts +65 -0
  62. package/dist/cjs/memory/ContentStorage.d.ts +7 -0
  63. package/dist/cjs/memory/SmartMemoryManager.d.ts +1 -0
  64. package/dist/cjs/services/ContentStoreManager.d.ts +11 -1
  65. package/dist/cjs/utils/ResponseFormatter.d.ts +26 -0
  66. package/dist/esm/index.js +8 -1
  67. package/dist/esm/index.js.map +1 -1
  68. package/dist/esm/index12.js +1 -1
  69. package/dist/esm/index12.js.map +1 -1
  70. package/dist/esm/index14.js +23 -5
  71. package/dist/esm/index14.js.map +1 -1
  72. package/dist/esm/index15.js +25 -4
  73. package/dist/esm/index15.js.map +1 -1
  74. package/dist/esm/index16.js +4 -2
  75. package/dist/esm/index16.js.map +1 -1
  76. package/dist/esm/index17.js +2 -7
  77. package/dist/esm/index17.js.map +1 -1
  78. package/dist/esm/index18.js +609 -36
  79. package/dist/esm/index18.js.map +1 -1
  80. package/dist/esm/index19.js +229 -84
  81. package/dist/esm/index19.js.map +1 -1
  82. package/dist/esm/index20.js +111 -17
  83. package/dist/esm/index20.js.map +1 -1
  84. package/dist/esm/index21.js +44 -7
  85. package/dist/esm/index21.js.map +1 -1
  86. package/dist/esm/index22.js +86 -157
  87. package/dist/esm/index22.js.map +1 -1
  88. package/dist/esm/index23.js +32 -150
  89. package/dist/esm/index23.js.map +1 -1
  90. package/dist/esm/index24.js +746 -80
  91. package/dist/esm/index24.js.map +1 -1
  92. package/dist/esm/index25.js +154 -45
  93. package/dist/esm/index25.js.map +1 -1
  94. package/dist/esm/index26.js +149 -24
  95. package/dist/esm/index26.js.map +1 -1
  96. package/dist/esm/index27.js +196 -217
  97. package/dist/esm/index27.js.map +1 -1
  98. package/dist/esm/index28.js +187 -0
  99. package/dist/esm/index28.js.map +1 -0
  100. package/dist/esm/index29.js +308 -0
  101. package/dist/esm/index29.js.map +1 -0
  102. package/dist/esm/index30.js +159 -0
  103. package/dist/esm/index30.js.map +1 -0
  104. package/dist/esm/index31.js +68 -0
  105. package/dist/esm/index31.js.map +1 -0
  106. package/dist/esm/index32.js +30 -0
  107. package/dist/esm/index32.js.map +1 -0
  108. package/dist/esm/index33.js +95 -0
  109. package/dist/esm/index33.js.map +1 -0
  110. package/dist/esm/index34.js +245 -0
  111. package/dist/esm/index34.js.map +1 -0
  112. package/dist/esm/index5.js +2 -2
  113. package/dist/esm/index5.js.map +1 -1
  114. package/dist/esm/index6.js +68 -25
  115. package/dist/esm/index6.js.map +1 -1
  116. package/dist/esm/index7.js.map +1 -1
  117. package/dist/esm/index8.js +744 -70
  118. package/dist/esm/index8.js.map +1 -1
  119. package/dist/types/base-agent.d.ts +2 -0
  120. package/dist/types/conversational-agent.d.ts +8 -0
  121. package/dist/types/core/ToolRegistry.d.ts +130 -0
  122. package/dist/types/execution/ExecutionPipeline.d.ts +81 -0
  123. package/dist/types/forms/FormEngine.d.ts +121 -0
  124. package/dist/types/forms/field-type-registry.d.ts +51 -0
  125. package/dist/types/forms/form-generator.d.ts +123 -0
  126. package/dist/types/forms/index.d.ts +2 -0
  127. package/dist/types/forms/types.d.ts +108 -0
  128. package/dist/types/index.d.ts +5 -0
  129. package/dist/types/langchain/FormAwareAgentExecutor.d.ts +108 -0
  130. package/dist/types/langchain/FormValidatingToolWrapper.d.ts +81 -0
  131. package/dist/types/langchain-agent.d.ts +65 -0
  132. package/dist/types/memory/ContentStorage.d.ts +7 -0
  133. package/dist/types/memory/SmartMemoryManager.d.ts +1 -0
  134. package/dist/types/services/ContentStoreManager.d.ts +11 -1
  135. package/dist/types/utils/ResponseFormatter.d.ts +26 -0
  136. package/package.json +35 -34
  137. package/src/base-agent.ts +2 -0
  138. package/src/config/system-message.ts +14 -0
  139. package/src/context/ReferenceContextManager.ts +1 -1
  140. package/src/conversational-agent.ts +95 -38
  141. package/src/core/ToolRegistry.ts +358 -0
  142. package/src/execution/ExecutionPipeline.ts +301 -0
  143. package/src/forms/FormEngine.ts +443 -0
  144. package/src/forms/field-type-registry.ts +203 -0
  145. package/src/forms/form-generator.ts +841 -0
  146. package/src/forms/index.ts +2 -0
  147. package/src/forms/types.ts +125 -0
  148. package/src/index.ts +9 -0
  149. package/src/langchain/FormAwareAgentExecutor.ts +971 -0
  150. package/src/langchain/FormValidatingToolWrapper.ts +355 -0
  151. package/src/langchain-agent.ts +1034 -87
  152. package/src/mcp/ContentProcessor.ts +20 -4
  153. package/src/mcp/MCPClientManager.ts +1 -1
  154. package/src/mcp/adapters/langchain.ts +1 -1
  155. package/src/memory/ContentStorage.ts +25 -5
  156. package/src/memory/SmartMemoryManager.ts +27 -4
  157. package/src/memory/TokenCounter.ts +1 -1
  158. package/src/plugins/hbar/HbarPlugin.ts +0 -1
  159. package/src/scripts/test-external-tool-wrapper.ts +103 -0
  160. package/src/scripts/test-hedera-kit-wrapper.ts +265 -0
  161. package/src/scripts/test-inscribe-form-generation.ts +494 -0
  162. package/src/scripts/test-inscribe-wrapper-verification.ts +220 -0
  163. package/src/services/ContentStoreManager.ts +23 -9
  164. package/src/services/EntityResolver.ts +2 -9
  165. package/src/tools/EntityResolverTool.ts +5 -8
  166. package/src/utils/ResponseFormatter.ts +146 -0
  167. package/cli/readme.md +0 -181
  168. package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +0 -14
  169. package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +0 -14
  170. package/src/langchain/ContentAwareAgentExecutor.ts +0 -19
@@ -0,0 +1,358 @@
1
+ import { StructuredTool } from '@langchain/core/tools';
2
+ import { z } from 'zod';
3
+ import { Logger } from '@hashgraphonline/standards-sdk';
4
+ import {
5
+ FormValidatingToolWrapper,
6
+ wrapToolWithFormValidation,
7
+ } from '../langchain/FormValidatingToolWrapper';
8
+ import { FormGenerator } from '../forms/form-generator';
9
+ import { isFormValidatable } from '@hashgraphonline/standards-agent-kit';
10
+
11
+ /**
12
+ * Tool capabilities configuration for registry entries
13
+ */
14
+ export interface ToolCapabilities {
15
+ supportsFormValidation: boolean;
16
+ requiresWrapper: boolean;
17
+ priority: 'low' | 'medium' | 'high' | 'critical';
18
+ category: 'core' | 'extension' | 'mcp';
19
+ }
20
+
21
+ /**
22
+ * Tool metadata for comprehensive tool information
23
+ */
24
+ export interface ToolMetadata {
25
+ name: string;
26
+ version: string;
27
+ category: ToolCapabilities['category'];
28
+ description: string;
29
+ capabilities: ToolCapabilities;
30
+ dependencies: string[];
31
+ schema: unknown;
32
+ }
33
+
34
+ /**
35
+ * Registry entry containing tool instance and metadata
36
+ */
37
+ export interface ToolRegistryEntry {
38
+ tool: StructuredTool;
39
+ metadata: ToolMetadata;
40
+ wrapper?: FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>> | undefined;
41
+ originalTool: StructuredTool;
42
+ }
43
+
44
+ /**
45
+ * Options for tool registration
46
+ */
47
+ export interface ToolRegistrationOptions {
48
+ forceWrapper?: boolean;
49
+ skipWrapper?: boolean;
50
+ wrapperConfig?: {
51
+ requireAllFields?: boolean;
52
+ skipFields?: string[];
53
+ };
54
+ metadata?: Partial<ToolMetadata>;
55
+ }
56
+
57
+ /**
58
+ * Query interface for finding tools
59
+ */
60
+ export interface ToolQuery {
61
+ name?: string;
62
+ category?: ToolMetadata['category'];
63
+ capabilities?: Partial<ToolCapabilities>;
64
+ }
65
+
66
+ /**
67
+ * Centralized tool registry for managing tool lifecycle
68
+ */
69
+ export class ToolRegistry {
70
+ private tools = new Map<string, ToolRegistryEntry>();
71
+ private formGenerator: FormGenerator;
72
+ private logger: Logger;
73
+
74
+ constructor(logger?: Logger) {
75
+ this.formGenerator = new FormGenerator();
76
+ this.logger = logger || new Logger({ module: 'ToolRegistry' });
77
+ }
78
+
79
+ /**
80
+ * Register a tool with the registry
81
+ */
82
+ registerTool(
83
+ tool: StructuredTool,
84
+ options: ToolRegistrationOptions = {}
85
+ ): void {
86
+ const capabilities = this.analyzeToolCapabilities(tool);
87
+ const metadata: ToolMetadata = {
88
+ name: tool.name,
89
+ version: '1.0.0',
90
+ category: options.metadata?.category || 'core',
91
+ description: tool.description,
92
+ capabilities,
93
+ dependencies: [],
94
+ schema: tool.schema,
95
+ ...options.metadata,
96
+ };
97
+
98
+ let finalTool: StructuredTool = tool;
99
+ let wrapper:
100
+ | FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>>
101
+ | undefined;
102
+
103
+ if (this.shouldWrapTool(tool, capabilities, options)) {
104
+ wrapper = wrapToolWithFormValidation(
105
+ tool as StructuredTool<z.ZodObject<z.ZodRawShape>>,
106
+ this.formGenerator,
107
+ {
108
+ requireAllFields: false,
109
+ skipFields: ['metaOptions'],
110
+ ...options.wrapperConfig,
111
+ }
112
+ ) as FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>>;
113
+ finalTool = wrapper as StructuredTool;
114
+ }
115
+
116
+ const entry: ToolRegistryEntry = {
117
+ tool: finalTool,
118
+ metadata,
119
+ wrapper,
120
+ originalTool: tool,
121
+ };
122
+
123
+ this.tools.set(tool.name, entry);
124
+ }
125
+
126
+ /**
127
+ * Get a tool by name
128
+ */
129
+ getTool(name: string): ToolRegistryEntry | null {
130
+ return this.tools.get(name) || null;
131
+ }
132
+
133
+ /**
134
+ * Get tools by capability
135
+ */
136
+ getToolsByCapability(
137
+ capability: keyof ToolCapabilities,
138
+ value?: unknown
139
+ ): ToolRegistryEntry[] {
140
+ const results: ToolRegistryEntry[] = [];
141
+
142
+ for (const entry of this.tools.values()) {
143
+ if (value !== undefined) {
144
+ if (entry.metadata.capabilities[capability] === value) {
145
+ results.push(entry);
146
+ }
147
+ } else if (entry.metadata.capabilities[capability]) {
148
+ results.push(entry);
149
+ }
150
+ }
151
+
152
+ return results;
153
+ }
154
+
155
+ /**
156
+ * Get tools by query
157
+ */
158
+ getToolsByQuery(query: ToolQuery): ToolRegistryEntry[] {
159
+ const results: ToolRegistryEntry[] = [];
160
+
161
+ for (const entry of this.tools.values()) {
162
+ let matches = true;
163
+
164
+ if (query.name && entry.metadata.name !== query.name) {
165
+ matches = false;
166
+ }
167
+
168
+ if (query.category && entry.metadata.category !== query.category) {
169
+ matches = false;
170
+ }
171
+
172
+ if (query.capabilities) {
173
+ for (const [key, value] of Object.entries(query.capabilities)) {
174
+ if (
175
+ entry.metadata.capabilities[key as keyof ToolCapabilities] !== value
176
+ ) {
177
+ matches = false;
178
+ break;
179
+ }
180
+ }
181
+ }
182
+
183
+ if (matches) {
184
+ results.push(entry);
185
+ }
186
+ }
187
+
188
+ return results;
189
+ }
190
+
191
+ /**
192
+ * Get all registered tools
193
+ */
194
+ getAllTools(): StructuredTool[] {
195
+ return Array.from(this.tools.values()).map((entry) => entry.tool);
196
+ }
197
+
198
+ /**
199
+ * Get all registry entries
200
+ */
201
+ getAllRegistryEntries(): ToolRegistryEntry[] {
202
+ return Array.from(this.tools.values());
203
+ }
204
+
205
+ /**
206
+ * Get all tool names
207
+ */
208
+ getToolNames(): string[] {
209
+ return Array.from(this.tools.keys());
210
+ }
211
+
212
+ /**
213
+ * Check if a tool is registered
214
+ */
215
+ hasTool(name: string): boolean {
216
+ return this.tools.has(name);
217
+ }
218
+
219
+ /**
220
+ * Unregister a tool
221
+ */
222
+ unregisterTool(name: string): boolean {
223
+ return this.tools.delete(name);
224
+ }
225
+
226
+ /**
227
+ * Clear all tools
228
+ */
229
+ clear(): void {
230
+ this.tools.clear();
231
+ }
232
+
233
+ /**
234
+ * Analyze tool capabilities
235
+ */
236
+ private analyzeToolCapabilities(tool: StructuredTool): ToolCapabilities {
237
+ const implementsFormValidatable = isFormValidatable(tool);
238
+ const hasRenderConfig = this.hasRenderConfig(tool);
239
+ const isZodObjectLike = this.isZodObjectLike(tool.schema);
240
+
241
+ const supportsFormValidation = implementsFormValidatable || hasRenderConfig;
242
+ const requiresWrapper = supportsFormValidation && isZodObjectLike;
243
+
244
+ let priority: ToolCapabilities['priority'] = 'medium';
245
+ let category: ToolCapabilities['category'] = 'core';
246
+
247
+ if (supportsFormValidation && requiresWrapper) {
248
+ priority = 'critical';
249
+ } else if (supportsFormValidation) {
250
+ priority = 'high';
251
+ } else if (
252
+ tool.description?.toLowerCase().includes('query') ||
253
+ tool.description?.toLowerCase().includes('search')
254
+ ) {
255
+ priority = 'low';
256
+ }
257
+
258
+ const toolAsAny = tool as unknown as Record<string, unknown>;
259
+ if (tool.constructor.name.includes('MCP') || toolAsAny.isMCPTool) {
260
+ category = 'mcp';
261
+ } else if (
262
+ toolAsAny.isExtension ||
263
+ tool.constructor.name.includes('Extension')
264
+ ) {
265
+ category = 'extension';
266
+ }
267
+
268
+ return {
269
+ supportsFormValidation,
270
+ requiresWrapper,
271
+ priority,
272
+ category,
273
+ };
274
+ }
275
+
276
+ /**
277
+ * Check if tool has render configuration
278
+ */
279
+ private hasRenderConfig(tool: StructuredTool): boolean {
280
+ const schema = tool.schema as Record<string, unknown>;
281
+ return !!(schema && schema._renderConfig);
282
+ }
283
+
284
+ /**
285
+ * Determine if tool should be wrapped
286
+ */
287
+ private shouldWrapTool(
288
+ tool: StructuredTool,
289
+ capabilities: ToolCapabilities,
290
+ options: ToolRegistrationOptions
291
+ ): boolean {
292
+ if (options.skipWrapper) {
293
+ return false;
294
+ }
295
+
296
+ if (options.forceWrapper) {
297
+ return true;
298
+ }
299
+
300
+ return capabilities.requiresWrapper;
301
+ }
302
+
303
+ /**
304
+ * Check if schema is ZodObject-like
305
+ */
306
+ private isZodObjectLike(schema: unknown): boolean {
307
+ if (!schema || typeof schema !== 'object') {
308
+ return false;
309
+ }
310
+
311
+ const schemaRecord = schema as Record<string, unknown>;
312
+ const schemaDef = schemaRecord._def as Record<string, unknown> | undefined;
313
+
314
+ return (
315
+ schema instanceof z.ZodObject ||
316
+ schemaDef?.typeName === 'ZodObject' ||
317
+ ('shape' in schemaRecord && typeof schemaRecord.shape === 'object')
318
+ );
319
+ }
320
+
321
+ /**
322
+ * Get statistics about the registry
323
+ */
324
+ getStatistics(): {
325
+ totalTools: number;
326
+ wrappedTools: number;
327
+ unwrappedTools: number;
328
+ categoryCounts: Record<ToolCapabilities['category'], number>;
329
+ priorityCounts: Record<ToolCapabilities['priority'], number>;
330
+ } {
331
+ const stats = {
332
+ totalTools: this.tools.size,
333
+ wrappedTools: 0,
334
+ unwrappedTools: 0,
335
+ categoryCounts: { core: 0, extension: 0, mcp: 0 } as Record<
336
+ ToolCapabilities['category'],
337
+ number
338
+ >,
339
+ priorityCounts: { low: 0, medium: 0, high: 0, critical: 0 } as Record<
340
+ ToolCapabilities['priority'],
341
+ number
342
+ >,
343
+ };
344
+
345
+ for (const entry of this.tools.values()) {
346
+ if (entry.wrapper) {
347
+ stats.wrappedTools++;
348
+ } else {
349
+ stats.unwrappedTools++;
350
+ }
351
+
352
+ stats.categoryCounts[entry.metadata.category]++;
353
+ stats.priorityCounts[entry.metadata.capabilities.priority]++;
354
+ }
355
+
356
+ return stats;
357
+ }
358
+ }
@@ -0,0 +1,301 @@
1
+ import { ZodError } from 'zod';
2
+ import { Logger } from '@hashgraphonline/standards-sdk';
3
+ import { SmartMemoryManager } from '../memory/SmartMemoryManager';
4
+ import { FormEngine, ToolExecutionResult } from '../forms/FormEngine';
5
+ import type { FormMessage, FormSubmission } from '../forms/types';
6
+ import type { ToolRegistry, ToolRegistryEntry } from '../core/ToolRegistry';
7
+
8
+ /**
9
+ * Session context for tool execution
10
+ */
11
+ export interface SessionContext {
12
+ sessionId: string;
13
+ userId?: string;
14
+ timestamp: number;
15
+ conversationId?: string;
16
+ }
17
+
18
+ /**
19
+ * Context passed through execution pipeline
20
+ */
21
+ export interface ExecutionContext {
22
+ toolName: string;
23
+ input: unknown;
24
+ session: SessionContext;
25
+ memory: SmartMemoryManager;
26
+ traceId: string;
27
+ toolEntry: ToolRegistryEntry;
28
+ }
29
+
30
+ /**
31
+ * Result of tool execution with metadata
32
+ */
33
+ export interface ExecutionResult extends ToolExecutionResult {
34
+ traceId: string;
35
+ executionTime: number;
36
+ }
37
+
38
+ /**
39
+ * ExecutionPipeline handles tool execution coordination
40
+ */
41
+ export class ExecutionPipeline {
42
+ private logger: Logger;
43
+ private toolRegistry: ToolRegistry;
44
+ private formEngine: FormEngine;
45
+ private memory: SmartMemoryManager;
46
+
47
+ constructor(
48
+ toolRegistry: ToolRegistry,
49
+ formEngine: FormEngine,
50
+ memory: SmartMemoryManager,
51
+ logger?: Logger
52
+ ) {
53
+ this.toolRegistry = toolRegistry;
54
+ this.formEngine = formEngine;
55
+ this.memory = memory;
56
+ this.logger = logger || new Logger({ module: 'ExecutionPipeline' });
57
+ }
58
+
59
+ /**
60
+ * Execute a tool through the pipeline
61
+ */
62
+ async execute(
63
+ toolName: string,
64
+ input: unknown,
65
+ sessionContext?: SessionContext
66
+ ): Promise<ExecutionResult> {
67
+ const traceId = `trace-${Date.now()}-${Math.random()
68
+ .toString(36)
69
+ .substr(2, 9)}`;
70
+ const startTime = Date.now();
71
+
72
+ const toolEntry = this.toolRegistry.getTool(toolName);
73
+ if (!toolEntry) {
74
+ throw new Error(`Tool not found in registry: ${toolName}`);
75
+ }
76
+
77
+ const context: ExecutionContext = {
78
+ toolName,
79
+ input,
80
+ session: sessionContext || this.buildDefaultSession(),
81
+ memory: this.memory,
82
+ traceId,
83
+ toolEntry,
84
+ };
85
+
86
+ try {
87
+ const shouldGenerateForm = await this.checkFormGeneration(context);
88
+ if (shouldGenerateForm.requiresForm && shouldGenerateForm.formMessage) {
89
+ return {
90
+ success: false,
91
+ output: 'Form generation required',
92
+ requiresForm: true,
93
+ formMessage: shouldGenerateForm.formMessage,
94
+ traceId,
95
+ executionTime: Date.now() - startTime,
96
+ };
97
+ }
98
+
99
+ const result = await this.executeToolDirect(context);
100
+
101
+ return {
102
+ success: true,
103
+ output: result,
104
+ traceId,
105
+ executionTime: Date.now() - startTime,
106
+ };
107
+ } catch (error) {
108
+ return this.handleExecutionError(
109
+ error,
110
+ context,
111
+ traceId,
112
+ Date.now() - startTime
113
+ );
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Execute tool with validation
119
+ */
120
+ async executeWithValidation(
121
+ toolName: string,
122
+ input: unknown,
123
+ sessionContext?: SessionContext
124
+ ): Promise<ExecutionResult> {
125
+ return this.execute(toolName, input, sessionContext);
126
+ }
127
+
128
+ /**
129
+ * Process form submission
130
+ */
131
+ async processFormSubmission(
132
+ toolName: string,
133
+ formId: string,
134
+ parameters: Record<string, unknown>,
135
+ sessionContext?: SessionContext
136
+ ): Promise<ExecutionResult> {
137
+ const traceId = `form-${Date.now()}-${Math.random()
138
+ .toString(36)
139
+ .substr(2, 9)}`;
140
+ const startTime = Date.now();
141
+
142
+ try {
143
+ const formSubmission: FormSubmission = {
144
+ formId,
145
+ toolName,
146
+ parameters,
147
+ timestamp: Date.now(),
148
+ };
149
+
150
+ const processedInput = await this.formEngine.processSubmission(
151
+ formSubmission
152
+ );
153
+
154
+ return this.execute(toolName, processedInput, sessionContext);
155
+ } catch (error) {
156
+ return {
157
+ success: false,
158
+ output: 'Form submission processing failed',
159
+ error: error instanceof Error ? error.message : String(error),
160
+ traceId,
161
+ executionTime: Date.now() - startTime,
162
+ };
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Check if form generation is required
168
+ */
169
+ private async checkFormGeneration(context: ExecutionContext): Promise<{
170
+ requiresForm: boolean;
171
+ formMessage?: FormMessage;
172
+ }> {
173
+ const inputRecord = context.input as Record<string, unknown>;
174
+ if (inputRecord?.__fromForm === true || inputRecord?.renderForm === false) {
175
+ return { requiresForm: false };
176
+ }
177
+
178
+ if (
179
+ !this.formEngine.shouldGenerateForm(context.toolEntry.tool, context.input)
180
+ ) {
181
+ return { requiresForm: false };
182
+ }
183
+
184
+ const formMessage = await this.formEngine.generateForm(
185
+ context.toolName,
186
+ context.toolEntry.tool,
187
+ context.input
188
+ );
189
+
190
+ if (formMessage) {
191
+ return { requiresForm: true, formMessage };
192
+ }
193
+
194
+ return { requiresForm: false };
195
+ }
196
+
197
+ /**
198
+ * Execute tool directly
199
+ */
200
+ private async executeToolDirect(context: ExecutionContext): Promise<string> {
201
+ const { toolEntry, input } = context;
202
+ const parameters = (input as Record<string, unknown>) || {};
203
+ const mergedArgs = { ...parameters, renderForm: false };
204
+
205
+ if (toolEntry.wrapper) {
206
+ return this.executeWrappedTool(toolEntry, mergedArgs);
207
+ }
208
+
209
+ return await toolEntry.tool.call(mergedArgs);
210
+ }
211
+
212
+ /**
213
+ * Execute wrapped tool
214
+ */
215
+ private async executeWrappedTool(
216
+ toolEntry: ToolRegistryEntry,
217
+ mergedArgs: Record<string, unknown>
218
+ ): Promise<string> {
219
+ const wrapper = toolEntry.wrapper;
220
+ if (!wrapper) {
221
+ throw new Error('Tool wrapper not found');
222
+ }
223
+
224
+ const wrapperAsAny = wrapper as unknown as {
225
+ executeOriginal?: (args: Record<string, unknown>) => Promise<string>;
226
+ originalTool?: {
227
+ call?: (args: Record<string, unknown>) => Promise<string>;
228
+ };
229
+ };
230
+
231
+ if (wrapperAsAny.executeOriginal) {
232
+ return await wrapperAsAny.executeOriginal(mergedArgs);
233
+ }
234
+
235
+ if (wrapperAsAny.originalTool?.call) {
236
+ return await wrapperAsAny.originalTool.call(mergedArgs);
237
+ }
238
+
239
+ return await toolEntry.originalTool.call(mergedArgs);
240
+ }
241
+
242
+ /**
243
+ * Handle execution error
244
+ */
245
+ private handleExecutionError(
246
+ error: unknown,
247
+ context: ExecutionContext,
248
+ traceId: string,
249
+ executionTime: number
250
+ ): ExecutionResult {
251
+ const errorMessage = error instanceof Error ? error.message : String(error);
252
+
253
+ if (error instanceof ZodError) {
254
+ return {
255
+ success: false,
256
+ output: 'Validation error occurred',
257
+ error: errorMessage,
258
+ traceId,
259
+ executionTime,
260
+ };
261
+ }
262
+
263
+ this.logger.error(`Tool execution failed: ${context.toolName}`, {
264
+ traceId,
265
+ error: errorMessage,
266
+ });
267
+
268
+ return {
269
+ success: false,
270
+ output: 'Tool execution failed',
271
+ error: errorMessage,
272
+ traceId,
273
+ executionTime,
274
+ };
275
+ }
276
+
277
+ /**
278
+ * Build default session context
279
+ */
280
+ private buildDefaultSession(): SessionContext {
281
+ return {
282
+ sessionId: `session-${Date.now()}-${Math.random()
283
+ .toString(36)
284
+ .substr(2, 9)}`,
285
+ timestamp: Date.now(),
286
+ };
287
+ }
288
+
289
+ /**
290
+ * Get statistics about the pipeline
291
+ */
292
+ getStatistics(): {
293
+ totalMiddleware: number;
294
+ registeredMiddleware: string[];
295
+ } {
296
+ return {
297
+ totalMiddleware: 0,
298
+ registeredMiddleware: [],
299
+ };
300
+ }
301
+ }