@hashgraphonline/conversational-agent 0.1.217 → 0.1.219

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 (288) hide show
  1. package/cli/readme.md +181 -0
  2. package/dist/cjs/constants/entity-references.d.ts +18 -0
  3. package/dist/cjs/constants/form-priorities.d.ts +24 -0
  4. package/dist/cjs/constants/index.d.ts +4 -0
  5. package/dist/cjs/constants/messages.d.ts +19 -0
  6. package/dist/cjs/constants/test-constants.d.ts +42 -0
  7. package/dist/cjs/conversational-agent.d.ts +3 -8
  8. package/dist/{types/core/ToolRegistry.d.ts → cjs/core/tool-registry.d.ts} +11 -1
  9. package/dist/{types/execution/ExecutionPipeline.d.ts → cjs/execution/execution-pipeline.d.ts} +3 -3
  10. package/dist/cjs/forms/field-guidance-registry.d.ts +108 -0
  11. package/dist/cjs/forms/form-generator.d.ts +2 -7
  12. package/dist/cjs/forms/index.d.ts +3 -0
  13. package/dist/cjs/forms/types.d.ts +9 -1
  14. package/dist/cjs/index.cjs +1 -1
  15. package/dist/cjs/index.cjs.map +1 -1
  16. package/dist/cjs/index.d.ts +7 -12
  17. package/dist/cjs/langchain/external-tool-wrapper.d.ts +101 -0
  18. package/dist/{types/langchain/FormAwareAgentExecutor.d.ts → cjs/langchain/form-aware-agent-executor.d.ts} +19 -4
  19. package/dist/cjs/langchain/index.d.ts +3 -0
  20. package/dist/{types → cjs/langchain}/langchain-agent.d.ts +15 -7
  21. package/dist/cjs/mcp/adapters/index.d.ts +1 -0
  22. package/dist/cjs/mcp/adapters/langchain.d.ts +1 -1
  23. package/dist/{types/mcp/ContentProcessor.d.ts → cjs/mcp/content-processor.d.ts} +1 -1
  24. package/dist/cjs/mcp/index.d.ts +5 -0
  25. package/dist/{types/mcp/MCPClientManager.d.ts → cjs/mcp/mcp-client-manager.d.ts} +1 -1
  26. package/dist/cjs/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
  27. package/dist/cjs/memory/index.d.ts +5 -7
  28. package/dist/{types/memory/MemoryWindow.d.ts → cjs/memory/memory-window.d.ts} +1 -1
  29. package/dist/{types/memory/SmartMemoryManager.d.ts → cjs/memory/smart-memory-manager.d.ts} +1 -1
  30. package/dist/cjs/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
  31. package/dist/cjs/services/context/resolution-context.d.ts +49 -0
  32. package/dist/cjs/services/entity-resolver.d.ts +58 -0
  33. package/dist/cjs/services/formatters/converters/index.d.ts +2 -0
  34. package/dist/cjs/services/formatters/converters/string-normalization-converter.d.ts +13 -0
  35. package/dist/cjs/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
  36. package/dist/cjs/services/formatters/format-converter-registry.d.ts +66 -0
  37. package/dist/cjs/services/formatters/index.d.ts +3 -0
  38. package/dist/cjs/services/formatters/types.d.ts +29 -0
  39. package/dist/cjs/services/index.d.ts +3 -0
  40. package/dist/cjs/services/resolution/resolution-pipeline.d.ts +44 -0
  41. package/dist/cjs/tools/index.d.ts +1 -0
  42. package/dist/cjs/utils/index.d.ts +1 -0
  43. package/dist/esm/index.js +40 -13
  44. package/dist/esm/index.js.map +1 -1
  45. package/dist/esm/index10.js +669 -13
  46. package/dist/esm/index10.js.map +1 -1
  47. package/dist/esm/index11.js +310 -95
  48. package/dist/esm/index11.js.map +1 -1
  49. package/dist/esm/index12.js +130 -95
  50. package/dist/esm/index12.js.map +1 -1
  51. package/dist/esm/index13.js +262 -153
  52. package/dist/esm/index13.js.map +1 -1
  53. package/dist/esm/index14.js +100 -664
  54. package/dist/esm/index14.js.map +1 -1
  55. package/dist/esm/index15.js +135 -408
  56. package/dist/esm/index15.js.map +1 -1
  57. package/dist/esm/index16.js +240 -122
  58. package/dist/esm/index16.js.map +1 -1
  59. package/dist/esm/index17.js +147 -135
  60. package/dist/esm/index17.js.map +1 -1
  61. package/dist/esm/index18.js +376 -533
  62. package/dist/esm/index18.js.map +1 -1
  63. package/dist/esm/index19.js +87 -214
  64. package/dist/esm/index19.js.map +1 -1
  65. package/dist/esm/index2.js +21 -4
  66. package/dist/esm/index2.js.map +1 -1
  67. package/dist/esm/index20.js +158 -92
  68. package/dist/esm/index20.js.map +1 -1
  69. package/dist/esm/index21.js +717 -44
  70. package/dist/esm/index21.js.map +1 -1
  71. package/dist/esm/index22.js +58 -96
  72. package/dist/esm/index22.js.map +1 -1
  73. package/dist/esm/index23.js +324 -34
  74. package/dist/esm/index23.js.map +1 -1
  75. package/dist/esm/index24.js +125 -712
  76. package/dist/esm/index24.js.map +1 -1
  77. package/dist/esm/index25.js +113 -133
  78. package/dist/esm/index25.js.map +1 -1
  79. package/dist/esm/index26.js +18 -152
  80. package/dist/esm/index26.js.map +1 -1
  81. package/dist/esm/index27.js +14 -210
  82. package/dist/esm/index27.js.map +1 -1
  83. package/dist/esm/index28.js +70 -173
  84. package/dist/esm/index28.js.map +1 -1
  85. package/dist/esm/index29.js +882 -220
  86. package/dist/esm/index29.js.map +1 -1
  87. package/dist/esm/index30.js +218 -126
  88. package/dist/esm/index30.js.map +1 -1
  89. package/dist/esm/index31.js +1258 -44
  90. package/dist/esm/index31.js.map +1 -1
  91. package/dist/esm/index32.js +132 -24
  92. package/dist/esm/index32.js.map +1 -1
  93. package/dist/esm/index33.js +104 -82
  94. package/dist/esm/index33.js.map +1 -1
  95. package/dist/esm/index34.js +43 -239
  96. package/dist/esm/index34.js.map +1 -1
  97. package/dist/esm/index35.js +106 -0
  98. package/dist/esm/index35.js.map +1 -0
  99. package/dist/esm/index36.js +24 -0
  100. package/dist/esm/index36.js.map +1 -0
  101. package/dist/esm/index37.js +8 -0
  102. package/dist/esm/index37.js.map +1 -0
  103. package/dist/esm/index38.js +15 -0
  104. package/dist/esm/index38.js.map +1 -0
  105. package/dist/esm/index39.js +258 -0
  106. package/dist/esm/index39.js.map +1 -0
  107. package/dist/esm/index40.js +187 -0
  108. package/dist/esm/index40.js.map +1 -0
  109. package/dist/esm/index41.js +30 -0
  110. package/dist/esm/index41.js.map +1 -0
  111. package/dist/esm/index42.js +10 -0
  112. package/dist/esm/index42.js.map +1 -0
  113. package/dist/esm/index43.js +95 -0
  114. package/dist/esm/index43.js.map +1 -0
  115. package/dist/esm/index5.js +2 -2
  116. package/dist/esm/index5.js.map +1 -1
  117. package/dist/esm/index6.js +44 -67
  118. package/dist/esm/index6.js.map +1 -1
  119. package/dist/esm/index7.js +9 -0
  120. package/dist/esm/index7.js.map +1 -1
  121. package/dist/esm/index8.js +13 -1095
  122. package/dist/esm/index8.js.map +1 -1
  123. package/dist/esm/index9.js +17 -13
  124. package/dist/esm/index9.js.map +1 -1
  125. package/dist/types/constants/entity-references.d.ts +18 -0
  126. package/dist/types/constants/form-priorities.d.ts +24 -0
  127. package/dist/types/constants/index.d.ts +4 -0
  128. package/dist/types/constants/messages.d.ts +19 -0
  129. package/dist/types/constants/test-constants.d.ts +42 -0
  130. package/dist/types/conversational-agent.d.ts +3 -8
  131. package/dist/{cjs/core/ToolRegistry.d.ts → types/core/tool-registry.d.ts} +11 -1
  132. package/dist/{cjs/execution/ExecutionPipeline.d.ts → types/execution/execution-pipeline.d.ts} +3 -3
  133. package/dist/types/forms/field-guidance-registry.d.ts +108 -0
  134. package/dist/types/forms/form-generator.d.ts +2 -7
  135. package/dist/types/forms/index.d.ts +3 -0
  136. package/dist/types/forms/types.d.ts +9 -1
  137. package/dist/types/index.d.ts +7 -12
  138. package/dist/types/langchain/external-tool-wrapper.d.ts +101 -0
  139. package/dist/{cjs/langchain/FormAwareAgentExecutor.d.ts → types/langchain/form-aware-agent-executor.d.ts} +19 -4
  140. package/dist/types/langchain/index.d.ts +3 -0
  141. package/dist/{cjs → types/langchain}/langchain-agent.d.ts +15 -7
  142. package/dist/types/mcp/adapters/index.d.ts +1 -0
  143. package/dist/types/mcp/adapters/langchain.d.ts +1 -1
  144. package/dist/{cjs/mcp/ContentProcessor.d.ts → types/mcp/content-processor.d.ts} +1 -1
  145. package/dist/types/mcp/index.d.ts +5 -0
  146. package/dist/{cjs/mcp/MCPClientManager.d.ts → types/mcp/mcp-client-manager.d.ts} +1 -1
  147. package/dist/types/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
  148. package/dist/types/memory/index.d.ts +5 -7
  149. package/dist/{cjs/memory/MemoryWindow.d.ts → types/memory/memory-window.d.ts} +1 -1
  150. package/dist/{cjs/memory/SmartMemoryManager.d.ts → types/memory/smart-memory-manager.d.ts} +1 -1
  151. package/dist/types/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
  152. package/dist/types/services/context/resolution-context.d.ts +49 -0
  153. package/dist/types/services/entity-resolver.d.ts +58 -0
  154. package/dist/types/services/formatters/converters/index.d.ts +2 -0
  155. package/dist/types/services/formatters/converters/string-normalization-converter.d.ts +13 -0
  156. package/dist/types/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
  157. package/dist/types/services/formatters/format-converter-registry.d.ts +66 -0
  158. package/dist/types/services/formatters/index.d.ts +3 -0
  159. package/dist/types/services/formatters/types.d.ts +29 -0
  160. package/dist/types/services/index.d.ts +3 -0
  161. package/dist/types/services/resolution/resolution-pipeline.d.ts +44 -0
  162. package/dist/types/tools/index.d.ts +1 -0
  163. package/dist/types/utils/index.d.ts +1 -0
  164. package/package.json +30 -27
  165. package/src/agent-factory.ts +1 -1
  166. package/src/base-agent.ts +9 -0
  167. package/src/config/system-message.ts +2 -15
  168. package/src/constants/entity-references.ts +23 -0
  169. package/src/constants/form-priorities.ts +25 -0
  170. package/src/constants/index.ts +4 -0
  171. package/src/constants/messages.ts +20 -0
  172. package/src/constants/test-constants.ts +49 -0
  173. package/src/conversational-agent.ts +42 -69
  174. package/src/core/{ToolRegistry.ts → tool-registry.ts} +71 -1
  175. package/src/examples/external-tool-wrapper-example.ts +56 -0
  176. package/src/execution/{ExecutionPipeline.ts → execution-pipeline.ts} +3 -3
  177. package/src/forms/field-guidance-registry.ts +415 -0
  178. package/src/forms/field-type-registry.ts +49 -48
  179. package/src/forms/{FormEngine.ts → form-engine.ts} +66 -43
  180. package/src/forms/form-generator.ts +91 -17
  181. package/src/forms/index.ts +4 -1
  182. package/src/forms/types.ts +9 -1
  183. package/src/index.ts +7 -37
  184. package/src/langchain/external-tool-wrapper.ts +90 -0
  185. package/src/langchain/{FormAwareAgentExecutor.ts → form-aware-agent-executor.ts} +615 -231
  186. package/src/langchain/{FormValidatingToolWrapper.ts → form-validating-tool-wrapper.ts} +2 -1
  187. package/src/langchain/index.ts +3 -0
  188. package/src/{langchain-agent.ts → langchain/langchain-agent.ts} +389 -113
  189. package/src/mcp/adapters/index.ts +1 -0
  190. package/src/mcp/adapters/langchain.ts +27 -18
  191. package/src/mcp/{ContentProcessor.ts → content-processor.ts} +71 -47
  192. package/src/mcp/index.ts +5 -0
  193. package/src/mcp/{MCPClientManager.ts → mcp-client-manager.ts} +2 -2
  194. package/src/memory/{ContentStorage.ts → content-storage.ts} +263 -167
  195. package/src/memory/index.ts +5 -8
  196. package/src/memory/{MemoryWindow.ts → memory-window.ts} +47 -24
  197. package/src/memory/{SmartMemoryManager.ts → smart-memory-manager.ts} +49 -22
  198. package/src/plugins/hbar/HbarPlugin.ts +1 -1
  199. package/src/plugins/hcs-10/HCS10Plugin.ts +46 -28
  200. package/src/scripts/test-external-tool-wrapper.ts +6 -6
  201. package/src/scripts/test-inscribe-form-generation.ts +22 -21
  202. package/src/scripts/test-inscribe-wrapper-verification.ts +5 -4
  203. package/src/services/{ContentStoreManager.ts → content-store-manager.ts} +75 -33
  204. package/src/services/context/resolution-context.ts +80 -0
  205. package/src/services/entity-resolver.ts +425 -0
  206. package/src/services/formatters/converters/index.ts +2 -0
  207. package/src/services/formatters/converters/string-normalization-converter.ts +106 -0
  208. package/src/services/formatters/converters/topic-id-to-hrl-converter.ts +25 -0
  209. package/src/services/formatters/format-converter-registry.ts +229 -0
  210. package/src/services/formatters/index.ts +3 -0
  211. package/src/services/formatters/types.ts +31 -0
  212. package/src/services/index.ts +3 -0
  213. package/src/services/resolution/resolution-pipeline.ts +106 -0
  214. package/src/tools/index.ts +1 -0
  215. package/src/types/content-reference.ts +87 -60
  216. package/src/utils/index.ts +1 -0
  217. package/cli/dist/CLIApp.d.ts +0 -9
  218. package/cli/dist/CLIApp.js +0 -127
  219. package/cli/dist/LocalConversationalAgent.d.ts +0 -37
  220. package/cli/dist/LocalConversationalAgent.js +0 -58
  221. package/cli/dist/app.d.ts +0 -16
  222. package/cli/dist/app.js +0 -13
  223. package/cli/dist/cli.d.ts +0 -2
  224. package/cli/dist/cli.js +0 -51
  225. package/cli/dist/components/AppContainer.d.ts +0 -16
  226. package/cli/dist/components/AppContainer.js +0 -24
  227. package/cli/dist/components/AppScreens.d.ts +0 -2
  228. package/cli/dist/components/AppScreens.js +0 -259
  229. package/cli/dist/components/ChatScreen.d.ts +0 -15
  230. package/cli/dist/components/ChatScreen.js +0 -39
  231. package/cli/dist/components/DebugLoadingScreen.d.ts +0 -5
  232. package/cli/dist/components/DebugLoadingScreen.js +0 -31
  233. package/cli/dist/components/LoadingScreen.d.ts +0 -2
  234. package/cli/dist/components/LoadingScreen.js +0 -16
  235. package/cli/dist/components/LoadingScreenDebug.d.ts +0 -5
  236. package/cli/dist/components/LoadingScreenDebug.js +0 -27
  237. package/cli/dist/components/MCPConfigScreen.d.ts +0 -28
  238. package/cli/dist/components/MCPConfigScreen.js +0 -168
  239. package/cli/dist/components/ScreenRouter.d.ts +0 -12
  240. package/cli/dist/components/ScreenRouter.js +0 -22
  241. package/cli/dist/components/SetupScreen.d.ts +0 -15
  242. package/cli/dist/components/SetupScreen.js +0 -65
  243. package/cli/dist/components/SingleLoadingScreen.d.ts +0 -5
  244. package/cli/dist/components/SingleLoadingScreen.js +0 -27
  245. package/cli/dist/components/StatusBadge.d.ts +0 -7
  246. package/cli/dist/components/StatusBadge.js +0 -28
  247. package/cli/dist/components/TerminalWindow.d.ts +0 -8
  248. package/cli/dist/components/TerminalWindow.js +0 -24
  249. package/cli/dist/components/WelcomeScreen.d.ts +0 -11
  250. package/cli/dist/components/WelcomeScreen.js +0 -47
  251. package/cli/dist/context/AppContext.d.ts +0 -68
  252. package/cli/dist/context/AppContext.js +0 -363
  253. package/cli/dist/hooks/useInitializeAgent.d.ts +0 -19
  254. package/cli/dist/hooks/useInitializeAgent.js +0 -28
  255. package/cli/dist/hooks/useStableState.d.ts +0 -38
  256. package/cli/dist/hooks/useStableState.js +0 -68
  257. package/cli/dist/managers/AgentManager.d.ts +0 -57
  258. package/cli/dist/managers/AgentManager.js +0 -119
  259. package/cli/dist/managers/ConfigManager.d.ts +0 -53
  260. package/cli/dist/managers/ConfigManager.js +0 -173
  261. package/cli/dist/types.d.ts +0 -31
  262. package/cli/dist/types.js +0 -19
  263. package/dist/cjs/context/ReferenceContextManager.d.ts +0 -84
  264. package/dist/cjs/context/ReferenceResponseProcessor.d.ts +0 -76
  265. package/dist/cjs/services/EntityResolver.d.ts +0 -26
  266. package/dist/types/context/ReferenceContextManager.d.ts +0 -84
  267. package/dist/types/context/ReferenceResponseProcessor.d.ts +0 -76
  268. package/dist/types/services/EntityResolver.d.ts +0 -26
  269. package/src/context/ReferenceContextManager.ts +0 -350
  270. package/src/context/ReferenceResponseProcessor.ts +0 -295
  271. package/src/scripts/test-hedera-kit-wrapper.ts +0 -265
  272. package/src/services/EntityResolver.ts +0 -128
  273. /package/dist/cjs/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
  274. /package/dist/cjs/langchain/{FormValidatingToolWrapper.d.ts → form-validating-tool-wrapper.d.ts} +0 -0
  275. /package/dist/cjs/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
  276. /package/dist/cjs/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
  277. /package/dist/cjs/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
  278. /package/dist/cjs/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
  279. /package/dist/types/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
  280. /package/dist/types/langchain/{FormValidatingToolWrapper.d.ts → form-validating-tool-wrapper.d.ts} +0 -0
  281. /package/dist/types/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
  282. /package/dist/types/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
  283. /package/dist/types/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
  284. /package/dist/types/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
  285. /package/src/memory/{ReferenceIdGenerator.ts → reference-id-generator.ts} +0 -0
  286. /package/src/memory/{TokenCounter.ts → token-counter.ts} +0 -0
  287. /package/src/tools/{EntityResolverTool.ts → entity-resolver-tool.ts} +0 -0
  288. /package/src/utils/{ResponseFormatter.ts → response-formatter.ts} +0 -0
@@ -2,7 +2,7 @@ import { AgentExecutor } from 'langchain/agents';
2
2
  import { ZodError, z } from 'zod';
3
3
  import { FormGenerator } from '../forms/form-generator';
4
4
  import type { FormMessage, FormSubmission } from '../forms/types';
5
- import { FormEngine } from '../forms/FormEngine';
5
+ import { FormEngine } from '../forms/form-engine';
6
6
  import { Logger } from '@hashgraphonline/standards-sdk';
7
7
  import type { AgentAction, AgentFinish, AgentStep } from 'langchain/agents';
8
8
  import type { ToolInterface } from '@langchain/core/tools';
@@ -10,7 +10,9 @@ import { isFormValidatable } from '@hashgraphonline/standards-agent-kit';
10
10
  import type { ChainValues } from '@langchain/core/utils/types';
11
11
  import type { CallbackManagerForChainRun } from '@langchain/core/callbacks/manager';
12
12
  import type { RunnableConfig } from '@langchain/core/runnables';
13
- import { ResponseFormatter } from '../utils/ResponseFormatter';
13
+ import { ResponseFormatter } from '../utils/response-formatter';
14
+
15
+ type BasicFieldType = 'text' | 'number' | 'select' | 'checkbox' | 'textarea';
14
16
 
15
17
  const globalPendingForms: Map<string, PendingFormData> = new Map();
16
18
 
@@ -33,7 +35,9 @@ interface PendingFormData {
33
35
  originalToolInput?: unknown;
34
36
  schema: unknown;
35
37
  toolRef?: ToolInterface | undefined;
36
- originalToolRef?: { call?: (args: Record<string, unknown>) => Promise<string> } | undefined;
38
+ originalToolRef?:
39
+ | { call?: (args: Record<string, unknown>) => Promise<string> }
40
+ | undefined;
37
41
  }
38
42
 
39
43
  interface ToolResponse {
@@ -57,6 +61,27 @@ interface IntermediateStepData {
57
61
  observation?: unknown;
58
62
  }
59
63
 
64
+ interface HashLinkBlock {
65
+ blockId: string;
66
+ hashLink: string;
67
+ template: string;
68
+ attributes: Record<string, unknown>;
69
+ }
70
+
71
+ interface ResponseMetadataWithHashLink {
72
+ hashLinkBlock?: HashLinkBlock;
73
+ [key: string]: unknown;
74
+ }
75
+
76
+ /**
77
+ * Parameter preprocessing callback interface
78
+ */
79
+ export interface ParameterPreprocessingCallback {
80
+ (toolName: string, parameters: Record<string, unknown>): Promise<
81
+ Record<string, unknown>
82
+ >;
83
+ }
84
+
60
85
  /**
61
86
  * Agent executor that intercepts Zod validation errors and generates forms,
62
87
  * and processes HashLink block responses for rich UI rendering
@@ -66,12 +91,51 @@ export class FormAwareAgentExecutor extends AgentExecutor {
66
91
  private formEngine: FormEngine;
67
92
  private formLogger: Logger;
68
93
  private pendingForms: Map<string, PendingFormData> = new Map();
94
+ private parameterPreprocessingCallback:
95
+ | ParameterPreprocessingCallback
96
+ | undefined;
97
+
98
+ /**
99
+ * Type guard to check if a Zod type is a ZodObject
100
+ */
101
+ private isZodObject(schema: unknown): schema is z.ZodObject<z.ZodRawShape> {
102
+ return schema instanceof z.ZodObject;
103
+ }
104
+
105
+ /**
106
+ * Type guard to check if metadata has hashLinkBlock
107
+ */
108
+ private hasHashLinkBlock(
109
+ metadata: unknown
110
+ ): metadata is ResponseMetadataWithHashLink & {
111
+ hashLinkBlock: HashLinkBlock;
112
+ } {
113
+ return (
114
+ typeof metadata === 'object' &&
115
+ metadata !== null &&
116
+ 'hashLinkBlock' in metadata &&
117
+ typeof (metadata as Record<string, unknown>).hashLinkBlock === 'object' &&
118
+ (metadata as Record<string, unknown>).hashLinkBlock !== null
119
+ );
120
+ }
69
121
 
70
122
  constructor(...args: ConstructorParameters<typeof AgentExecutor>) {
71
123
  super(...args);
72
124
  this.formGenerator = new FormGenerator();
73
- this.formEngine = new FormEngine(new Logger({ module: 'FormAwareAgentExecutor.FormEngine' }));
125
+ this.formEngine = new FormEngine(
126
+ new Logger({ module: 'FormAwareAgentExecutor.FormEngine' })
127
+ );
74
128
  this.formLogger = new Logger({ module: 'FormAwareAgentExecutor' });
129
+ this.parameterPreprocessingCallback = undefined;
130
+ }
131
+
132
+ /**
133
+ * Set parameter preprocessing callback
134
+ */
135
+ setParameterPreprocessingCallback(
136
+ callback: ParameterPreprocessingCallback | undefined
137
+ ): void {
138
+ this.parameterPreprocessingCallback = callback;
75
139
  }
76
140
 
77
141
  /**
@@ -87,11 +151,15 @@ export class FormAwareAgentExecutor extends AgentExecutor {
87
151
  ): Promise<AgentFinish | AgentStep[]> {
88
152
  this.formLogger.info('🛡️ BULLETPROOF INTERCEPTION: _takeNextStep called', {
89
153
  availableTools: Object.keys(nameToolMap),
90
- inputKeys: Object.keys(inputs)
154
+ inputKeys: Object.keys(inputs),
91
155
  });
92
156
 
93
- const result = await this.agent.plan(intermediateSteps, inputs, runManager?.getChild());
94
-
157
+ const result = await this.agent.plan(
158
+ intermediateSteps,
159
+ inputs,
160
+ runManager?.getChild()
161
+ );
162
+
95
163
  if ('returnValues' in result) {
96
164
  this.formLogger.info('Agent returned finish action, passing through');
97
165
  return result;
@@ -104,89 +172,119 @@ export class FormAwareAgentExecutor extends AgentExecutor {
104
172
  this.formLogger.info(`🎯 INTERCEPTING TOOL CALL: ${toolName}`, {
105
173
  toolInput,
106
174
  hasInNameToolMap: toolName in nameToolMap,
107
- toolInputKeys: Object.keys(toolInput || {})
175
+ toolInputKeys: Object.keys(toolInput || {}),
108
176
  });
109
177
 
110
- const tool = nameToolMap[toolName] || this.tools.find(t => t.name === toolName);
111
-
178
+ const tool =
179
+ nameToolMap[toolName] || this.tools.find((t) => t.name === toolName);
180
+
112
181
  if (!tool) {
113
182
  this.formLogger.error(`Tool ${toolName} not found in registry`);
114
183
  throw new Error(`Tool "${toolName}" not found`);
115
184
  }
116
185
 
117
186
  let shouldGenerateForm = false;
118
-
187
+
119
188
  if (isFormValidatable(tool)) {
120
- this.formLogger.info(`🔍 Tool ${toolName} implements FormValidatable, checking shouldGenerateForm()`, {
121
- toolInput
122
- });
123
-
189
+ this.formLogger.info(
190
+ `🔍 Tool ${toolName} implements FormValidatable, checking shouldGenerateForm()`,
191
+ {
192
+ toolInput,
193
+ }
194
+ );
195
+
124
196
  try {
125
197
  shouldGenerateForm = tool.shouldGenerateForm(toolInput);
126
- this.formLogger.info(`FormValidatable.shouldGenerateForm() result: ${shouldGenerateForm}`, {
127
- toolName,
128
- toolInput
129
- });
198
+ this.formLogger.info(
199
+ `FormValidatable.shouldGenerateForm() result: ${shouldGenerateForm}`,
200
+ {
201
+ toolName,
202
+ toolInput,
203
+ }
204
+ );
130
205
  } catch (error) {
131
- this.formLogger.error(`Error calling shouldGenerateForm() on ${toolName}:`, error);
206
+ this.formLogger.error(
207
+ `Error calling shouldGenerateForm() on ${toolName}:`,
208
+ error
209
+ );
132
210
  shouldGenerateForm = false;
133
211
  }
134
212
  }
135
213
 
136
214
  if (shouldGenerateForm) {
137
215
  this.formLogger.info(`🚨 FORM GENERATION TRIGGERED for ${toolName}`);
138
-
216
+
139
217
  try {
140
218
  let schemaToUse: z.ZodSchema;
141
219
  let isFocusedSchema = false;
142
-
220
+
143
221
  if (isFormValidatable(tool)) {
144
- this.formLogger.info(`🎯 Tool ${toolName} is FormValidatable, attempting to get focused schema`);
222
+ this.formLogger.info(
223
+ `🎯 Tool ${toolName} is FormValidatable, attempting to get focused schema`
224
+ );
145
225
  try {
146
226
  const focusedSchema = tool.getFormSchema();
147
227
  if (focusedSchema) {
148
228
  schemaToUse = focusedSchema;
149
229
  isFocusedSchema = true;
150
- this.formLogger.info(`✅ Successfully obtained focused schema for ${toolName}`);
230
+ this.formLogger.info(
231
+ `✅ Successfully obtained focused schema for ${toolName}`
232
+ );
151
233
  } else {
152
- this.formLogger.warn(`getFormSchema() returned null/undefined for ${toolName}, using default schema`);
234
+ this.formLogger.warn(
235
+ `getFormSchema() returned null/undefined for ${toolName}, using default schema`
236
+ );
153
237
  schemaToUse = tool.schema;
154
238
  isFocusedSchema = false;
155
239
  }
156
240
  } catch (error) {
157
- this.formLogger.error(`Failed to get focused schema from ${toolName}:`, error);
158
- this.formLogger.info(`Falling back to default schema for ${toolName}`);
241
+ this.formLogger.error(
242
+ `Failed to get focused schema from ${toolName}:`,
243
+ error
244
+ );
245
+ this.formLogger.info(
246
+ `Falling back to default schema for ${toolName}`
247
+ );
159
248
  schemaToUse = tool.schema;
160
249
  isFocusedSchema = false;
161
250
  }
162
251
  } else {
163
- this.formLogger.info(`Tool ${toolName} is not FormValidatable, using default schema`);
252
+ this.formLogger.info(
253
+ `Tool ${toolName} is not FormValidatable, using default schema`
254
+ );
164
255
  schemaToUse = tool.schema;
165
256
  isFocusedSchema = false;
166
257
  }
167
258
 
168
259
  let schemaFieldCount = 'unknown';
169
260
  try {
170
- if (schemaToUse && typeof schemaToUse === 'object' && 'shape' in schemaToUse) {
171
- const shape = (schemaToUse as any).shape;
261
+ if (this.isZodObject(schemaToUse)) {
262
+ const zodObject = schemaToUse as z.ZodObject<z.ZodRawShape>;
263
+ const shape = zodObject.shape;
172
264
  if (shape && typeof shape === 'object') {
173
265
  schemaFieldCount = Object.keys(shape).length.toString();
174
266
  }
175
267
  }
176
- } catch {
177
- }
178
-
179
- this.formLogger.info(`📋 Generating form with ${isFocusedSchema ? 'FOCUSED' : 'DEFAULT'} schema`, {
180
- toolName,
181
- schemaType: schemaToUse?.constructor?.name,
182
- estimatedFieldCount: schemaFieldCount,
183
- isFocusedSchema
184
- });
268
+ } catch {}
269
+
270
+ this.formLogger.info(
271
+ `📋 Generating form with ${
272
+ isFocusedSchema ? 'FOCUSED' : 'DEFAULT'
273
+ } schema`,
274
+ {
275
+ toolName,
276
+ schemaType: schemaToUse?.constructor?.name,
277
+ estimatedFieldCount: schemaFieldCount,
278
+ isFocusedSchema,
279
+ }
280
+ );
185
281
 
186
282
  let missingFields: Set<string> | undefined;
187
-
283
+
188
284
  if (isFocusedSchema) {
189
- this.formLogger.info(`⭐ Using focused schema - letting FormGenerator determine fields from schema`);
285
+ this.formLogger.info(
286
+ `⭐ Using focused schema - letting FormGenerator determine fields from schema`
287
+ );
190
288
  missingFields = undefined;
191
289
  } else {
192
290
  missingFields = new Set<string>();
@@ -195,38 +293,42 @@ export class FormAwareAgentExecutor extends AgentExecutor {
195
293
  const shape = zodObject.shape || {};
196
294
  for (const fieldName of Object.keys(shape)) {
197
295
  const value = (toolInput || {})[fieldName];
198
-
199
- const isEmpty = (isFormValidatable(tool) && tool.isFieldEmpty)
200
- ? tool.isFieldEmpty(fieldName, value)
201
- : (value === undefined ||
202
- value === '' ||
203
- value === null ||
204
- (Array.isArray(value) && value.length === 0));
205
-
296
+
297
+ const isEmpty =
298
+ isFormValidatable(tool) && tool.isFieldEmpty
299
+ ? tool.isFieldEmpty(fieldName, value)
300
+ : value === undefined ||
301
+ value === '' ||
302
+ value === null ||
303
+ (Array.isArray(value) && value.length === 0);
304
+
206
305
  const isRequired = this.isFieldRequired(schemaToUse, fieldName);
207
-
208
- const isEssential = (isFormValidatable(tool) && tool.getEssentialFields)
209
- ? tool.getEssentialFields().includes(fieldName)
210
- : false;
211
-
306
+
307
+ const isEssential =
308
+ isFormValidatable(tool) && tool.getEssentialFields
309
+ ? tool.getEssentialFields().includes(fieldName)
310
+ : false;
311
+
212
312
  this.formLogger.info(`🔍 Field analysis: ${fieldName}`, {
213
313
  value: value,
214
314
  isEmpty: isEmpty,
215
315
  isRequired: isRequired,
216
316
  isEssential: isEssential,
217
- willAddToMissingFields: isEmpty && (isRequired || isEssential)
317
+ willAddToMissingFields: isEmpty && (isRequired || isEssential),
218
318
  });
219
-
319
+
220
320
  if (isEmpty && (isRequired || isEssential)) {
221
321
  missingFields.add(fieldName);
222
322
  }
223
323
  }
224
324
  }
225
-
325
+
226
326
  this.formLogger.info(`📋 Missing fields analysis complete`, {
227
- totalFields: this.isZodObject(schemaToUse) ? Object.keys(schemaToUse.shape).length : 0,
327
+ totalFields: this.isZodObject(schemaToUse)
328
+ ? Object.keys(schemaToUse.shape).length
329
+ : 0,
228
330
  missingFieldsCount: missingFields.size,
229
- missingFields: Array.from(missingFields)
331
+ missingFields: Array.from(missingFields),
230
332
  });
231
333
  }
232
334
 
@@ -235,34 +337,44 @@ export class FormAwareAgentExecutor extends AgentExecutor {
235
337
  toolInput,
236
338
  {
237
339
  toolName: toolName,
238
- toolDescription: tool.description
340
+ toolDescription: tool.description,
239
341
  },
240
- missingFields // Pass undefined for focused schemas, Set<string> for others
342
+ missingFields // Pass undefined for focused schemas, Set<string> for others
241
343
  );
242
344
 
243
345
  if (this.isZodObject(schemaToUse)) {
244
346
  try {
245
- const { jsonSchema, uiSchema } = this.formGenerator.generateJsonSchemaForm(
246
- schemaToUse,
247
- toolInput as Record<string, unknown> | undefined,
248
- missingFields
249
- );
347
+ const { jsonSchema, uiSchema } =
348
+ this.formGenerator.generateJsonSchemaForm(
349
+ schemaToUse,
350
+ toolInput as Record<string, unknown> | undefined,
351
+ missingFields
352
+ );
250
353
  formMessage.jsonSchema = jsonSchema;
251
354
  formMessage.uiSchema = uiSchema;
252
355
  } catch (error) {
253
- this.formLogger.warn('Failed to generate JSON Schema for RJSF:', error);
356
+ this.formLogger.warn(
357
+ 'Failed to generate JSON Schema for RJSF:',
358
+ error
359
+ );
254
360
  }
255
361
  }
256
362
 
257
363
  formMessage.partialInput = toolInput;
258
-
364
+
259
365
  const formData: PendingFormData = {
260
366
  toolName: toolName,
261
367
  originalInput: inputs,
262
368
  originalToolInput: toolInput,
263
369
  schema: schemaToUse,
264
370
  toolRef: tool as ToolInterface | undefined,
265
- originalToolRef: (tool as unknown as { originalTool?: { call?: (args: Record<string, unknown>) => Promise<string> } }).originalTool
371
+ originalToolRef: (
372
+ tool as unknown as {
373
+ originalTool?: {
374
+ call?: (args: Record<string, unknown>) => Promise<string>;
375
+ };
376
+ }
377
+ ).originalTool,
266
378
  };
267
379
  this.pendingForms.set(formMessage.id, formData);
268
380
  globalPendingForms.set(formMessage.id, formData);
@@ -271,33 +383,155 @@ export class FormAwareAgentExecutor extends AgentExecutor {
271
383
 
272
384
  const formResult = {
273
385
  requiresForm: true,
274
- formMessage
386
+ formMessage,
275
387
  };
276
388
 
277
- return [{
278
- action: action,
279
- observation: JSON.stringify(formResult)
280
- }];
281
-
389
+ return [
390
+ {
391
+ action: action,
392
+ observation: JSON.stringify(formResult),
393
+ },
394
+ ];
282
395
  } catch (error) {
283
396
  this.formLogger.error(`Form generation failed for ${toolName}:`, error);
284
-
285
397
  }
286
398
  }
287
399
 
288
- this.formLogger.info(`⚪ Passing through to normal tool execution for ${toolName}`);
289
- return super._takeNextStep(nameToolMap, inputs, intermediateSteps, runManager, config);
290
- }
400
+ this.formLogger.info(
401
+ `⚪ Passing through to normal tool execution for ${toolName}`
402
+ );
291
403
 
292
- /**
293
- * Type guard to check if a schema is a ZodObject
294
- */
295
- private isZodObject(schema: unknown): schema is z.ZodObject<z.ZodRawShape> {
296
- if (!schema || typeof schema !== 'object') {
297
- return false;
404
+ if (this.parameterPreprocessingCallback && toolInput) {
405
+ this.formLogger.info(
406
+ `🔄 Applying parameter preprocessing for ${toolName}`
407
+ );
408
+ try {
409
+ const preprocessedInput = await this.parameterPreprocessingCallback(
410
+ toolName,
411
+ toolInput as Record<string, unknown>
412
+ );
413
+
414
+ if (
415
+ preprocessedInput &&
416
+ typeof preprocessedInput === 'object' &&
417
+ '__requestForm' in (preprocessedInput as Record<string, unknown>)
418
+ ) {
419
+ const rf = (preprocessedInput as Record<string, unknown>).__requestForm as {
420
+ id?: string;
421
+ title?: string;
422
+ description?: string;
423
+ fields?: Array<{
424
+ name: string;
425
+ label: string;
426
+ type: string;
427
+ required?: boolean;
428
+ options?: Array<{ value: string; label: string }>;
429
+ }>;
430
+ submitLabel?: string;
431
+ };
432
+
433
+ const formId = rf.id || `form_${Date.now()}_${Math.random().toString(36).slice(2)}`;
434
+ const formMessage = {
435
+ type: 'form',
436
+ id: formId,
437
+ originalPrompt: 'Parameter validation required',
438
+ toolName,
439
+ formConfig: {
440
+ title: rf.title || 'Complete required parameters',
441
+ description:
442
+ rf.description ||
443
+ 'One or more parameters require confirmation. Please review and submit.',
444
+ submitLabel: rf.submitLabel || 'Continue',
445
+ fields: (rf.fields || []).map((f) => {
446
+ const allowedTypes: BasicFieldType[] = [
447
+ 'text',
448
+ 'number',
449
+ 'select',
450
+ 'checkbox',
451
+ 'textarea',
452
+ ];
453
+ const resolvedType: BasicFieldType = allowedTypes.includes(
454
+ f.type as BasicFieldType
455
+ )
456
+ ? (f.type as BasicFieldType)
457
+ : 'text';
458
+
459
+ return {
460
+ name: f.name,
461
+ label: f.label,
462
+ type: resolvedType,
463
+ required: f.required ?? true,
464
+ options: f.options,
465
+ };
466
+ }),
467
+ },
468
+ };
469
+
470
+ const resolvedSchema = isFormValidatable(tool)
471
+ ? (() => {
472
+ try {
473
+ const s = tool.getFormSchema();
474
+ return s || tool.schema;
475
+ } catch {
476
+ return tool.schema;
477
+ }
478
+ })()
479
+ : tool.schema;
480
+
481
+ this.pendingForms.set(formId, {
482
+ toolName,
483
+ originalInput: inputs,
484
+ originalToolInput: toolInput,
485
+ schema: resolvedSchema,
486
+ toolRef: tool as ToolInterface | undefined,
487
+ originalToolRef: (
488
+ tool as unknown as { originalTool?: { call?: (a: Record<string, unknown>) => Promise<string> } }
489
+ ).originalTool,
490
+ });
491
+ globalPendingForms.set(formId, {
492
+ toolName,
493
+ originalInput: inputs,
494
+ originalToolInput: toolInput,
495
+ schema: resolvedSchema,
496
+ });
497
+
498
+ return [
499
+ {
500
+ action,
501
+ observation: JSON.stringify({ requiresForm: true, formMessage }),
502
+ },
503
+ ];
504
+ }
505
+
506
+ if (JSON.stringify(preprocessedInput) !== JSON.stringify(toolInput)) {
507
+ this.formLogger.info(`📝 Parameters preprocessed for ${toolName}:`, {
508
+ original: Object.keys(toolInput as Record<string, unknown>),
509
+ preprocessed: Object.keys(preprocessedInput),
510
+ hasChanges: true,
511
+ });
512
+
513
+ try {
514
+ (action as unknown as { toolInput?: Record<string, unknown> }).toolInput =
515
+ preprocessedInput as Record<string, unknown>;
516
+ } catch {}
517
+ } else {
518
+ this.formLogger.debug(`No parameter changes needed for ${toolName}`);
519
+ }
520
+ } catch (preprocessError) {
521
+ this.formLogger.warn(
522
+ `Parameter preprocessing failed for ${toolName}, using original parameters:`,
523
+ preprocessError
524
+ );
525
+ }
298
526
  }
299
- const candidate = schema as { _def?: { typeName?: string } };
300
- return Boolean(candidate._def && candidate._def.typeName === 'ZodObject');
527
+
528
+ return super._takeNextStep(
529
+ nameToolMap,
530
+ inputs,
531
+ intermediateSteps,
532
+ runManager,
533
+ config
534
+ );
301
535
  }
302
536
 
303
537
  /**
@@ -314,9 +548,10 @@ export class FormAwareAgentExecutor extends AgentExecutor {
314
548
  if (!def || def.typeName !== 'ZodObject') {
315
549
  return false;
316
550
  }
317
- const rawShape: unknown = typeof (def as { shape?: unknown }).shape === 'function'
318
- ? (def as { shape: () => Record<string, z.ZodTypeAny> }).shape()
319
- : (def as { shape?: Record<string, z.ZodTypeAny> }).shape;
551
+ const rawShape: unknown =
552
+ typeof (def as { shape?: unknown }).shape === 'function'
553
+ ? (def as { shape: () => Record<string, z.ZodTypeAny> }).shape()
554
+ : (def as { shape?: Record<string, z.ZodTypeAny> }).shape;
320
555
  if (!rawShape || typeof rawShape !== 'object') {
321
556
  return false;
322
557
  }
@@ -326,14 +561,22 @@ export class FormAwareAgentExecutor extends AgentExecutor {
326
561
  return false;
327
562
  }
328
563
  const unwrapOptional = (s: z.ZodTypeAny): z.ZodTypeAny => {
329
- const inner = (s as unknown as { _def?: { typeName?: string; innerType?: z.ZodTypeAny } })._def;
564
+ const inner = (
565
+ s as unknown as {
566
+ _def?: { typeName?: string; innerType?: z.ZodTypeAny };
567
+ }
568
+ )._def;
330
569
  if (inner && inner.typeName === 'ZodOptional' && inner.innerType) {
331
570
  return inner.innerType;
332
571
  }
333
572
  return s;
334
573
  };
335
574
  const unwrapped = unwrapOptional(fieldSchema);
336
- const fdef = (unwrapped as unknown as { _def?: { typeName?: string; defaultValue?: unknown } })._def;
575
+ const fdef = (
576
+ unwrapped as unknown as {
577
+ _def?: { typeName?: string; defaultValue?: unknown };
578
+ }
579
+ )._def;
337
580
  if (!fdef) {
338
581
  return true;
339
582
  }
@@ -345,7 +588,10 @@ export class FormAwareAgentExecutor extends AgentExecutor {
345
588
  }
346
589
  return true;
347
590
  } catch (error) {
348
- this.formLogger.debug(`Could not determine if field ${fieldPath} is required:`, error);
591
+ this.formLogger.debug(
592
+ `Could not determine if field ${fieldPath} is required:`,
593
+ error
594
+ );
349
595
  }
350
596
  return false;
351
597
  }
@@ -353,69 +599,83 @@ export class FormAwareAgentExecutor extends AgentExecutor {
353
599
  /**
354
600
  * Override _call to intercept Zod validation errors at the execution level
355
601
  */
356
- override async _call(inputs: Record<string, unknown>): Promise<Record<string, unknown>> {
602
+ override async _call(
603
+ inputs: Record<string, unknown>
604
+ ): Promise<Record<string, unknown>> {
357
605
  try {
358
606
  const result = await super._call(inputs);
359
-
607
+
360
608
  if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {
361
609
  for (const step of result.intermediateSteps) {
362
610
  if (step.observation) {
363
611
  try {
364
- const parsed: ToolResponse = typeof step.observation === 'string'
365
- ? JSON.parse(step.observation)
366
- : step.observation as ToolResponse;
367
-
612
+ const parsed: ToolResponse =
613
+ typeof step.observation === 'string'
614
+ ? JSON.parse(step.observation)
615
+ : (step.observation as ToolResponse);
616
+
368
617
  if (parsed.requiresForm && parsed.formMessage) {
369
618
  this.formLogger.info('Tool requested form generation', {
370
619
  toolName: step.action?.tool,
371
- hasForm: true
620
+ hasForm: true,
372
621
  });
373
-
374
- const actionToolName = (step as IntermediateStepData).action?.tool || 'unknown';
375
- const toolInstance = this.tools.find(t => t.name === actionToolName) as ToolInterface | undefined;
376
- const originalToolCandidate = (toolInstance as unknown as { originalTool?: { call?: (args: Record<string, unknown>) => Promise<string> } }) || {};
622
+
623
+ const actionToolName =
624
+ (step as IntermediateStepData).action?.tool || 'unknown';
625
+ const toolInstance = this.tools.find(
626
+ (t) => t.name === actionToolName
627
+ ) as ToolInterface | undefined;
628
+ const originalToolCandidate =
629
+ (toolInstance as unknown as {
630
+ originalTool?: {
631
+ call?: (args: Record<string, unknown>) => Promise<string>;
632
+ };
633
+ }) || {};
377
634
  const pf: PendingFormData = {
378
635
  toolName: actionToolName,
379
636
  originalInput: inputs,
380
- originalToolInput: (step as IntermediateStepData).action?.toolInput as Record<string, unknown> | undefined,
637
+ originalToolInput: (step as IntermediateStepData).action
638
+ ?.toolInput as Record<string, unknown> | undefined,
381
639
  schema: null,
382
640
  toolRef: toolInstance,
383
- originalToolRef: originalToolCandidate?.originalTool
641
+ originalToolRef: originalToolCandidate?.originalTool,
384
642
  };
385
643
  this.pendingForms.set(parsed.formMessage.id, pf);
386
644
  globalPendingForms.set(parsed.formMessage.id, pf);
387
-
645
+
388
646
  return {
389
647
  ...result,
390
648
  requiresForm: true,
391
649
  formMessage: parsed.formMessage,
392
- output: parsed.message || 'Please complete the form to continue.'
650
+ output:
651
+ parsed.message || 'Please complete the form to continue.',
393
652
  };
394
653
  }
395
-
396
- if (parsed.hashLinkBlock || (parsed.success && parsed.inscription && parsed.hashLinkBlock)) {
654
+
655
+ if (
656
+ parsed.hashLinkBlock ||
657
+ (parsed.success && parsed.inscription && parsed.hashLinkBlock)
658
+ ) {
397
659
  this.formLogger.info('Tool returned HashLink blocks', {
398
660
  toolName: (step as IntermediateStepData).action?.tool,
399
661
  hasHashLink: true,
400
- blockId: parsed.hashLinkBlock?.blockId
662
+ blockId: parsed.hashLinkBlock?.blockId,
401
663
  });
402
-
664
+
403
665
  const hashLinkResponse = this.processHashLinkResponse(parsed);
404
-
666
+
405
667
  return {
406
668
  ...result,
407
669
  hasHashLinkBlocks: true,
408
670
  hashLinkBlock: hashLinkResponse.hashLinkBlock,
409
- output: hashLinkResponse.message
671
+ output: hashLinkResponse.message,
410
672
  };
411
673
  }
412
- } catch {
413
-
414
- }
674
+ } catch {}
415
675
  }
416
676
  }
417
677
  }
418
-
678
+
419
679
  return result;
420
680
  } catch (error) {
421
681
  if (error instanceof ZodError) {
@@ -436,16 +696,24 @@ export class FormAwareAgentExecutor extends AgentExecutor {
436
696
  ): Promise<Record<string, unknown>> {
437
697
  this.formLogger.info('Zod validation error detected, generating form', {
438
698
  errorIssues: error.issues.length,
439
- inputKeys: Object.keys(inputs)
699
+ inputKeys: Object.keys(inputs),
440
700
  });
441
701
 
442
- let toolInfo = this.extractToolInfoFromError(error, inputs, intermediateSteps);
443
-
702
+ let toolInfo = this.extractToolInfoFromError(
703
+ error,
704
+ inputs,
705
+ intermediateSteps
706
+ );
707
+
444
708
  if (!toolInfo) {
445
- this.formLogger.warn('Could not extract tool info from validation error, trying fallback detection');
709
+ this.formLogger.warn(
710
+ 'Could not extract tool info from validation error, trying fallback detection'
711
+ );
446
712
  const fallbackTool = this.detectToolFromErrorContext(error);
447
713
  if (!fallbackTool) {
448
- this.formLogger.error('No tool detected for form generation, rethrowing error');
714
+ this.formLogger.error(
715
+ 'No tool detected for form generation, rethrowing error'
716
+ );
449
717
  throw error;
450
718
  }
451
719
  toolInfo = fallbackTool;
@@ -453,7 +721,7 @@ export class FormAwareAgentExecutor extends AgentExecutor {
453
721
 
454
722
  this.formLogger.info('Generating form for tool:', {
455
723
  toolName: toolInfo.toolName,
456
- hasSchema: !!toolInfo.schema
724
+ hasSchema: !!toolInfo.schema,
457
725
  });
458
726
 
459
727
  const formMessage = this.formGenerator.generateFormFromError(
@@ -466,20 +734,20 @@ export class FormAwareAgentExecutor extends AgentExecutor {
466
734
  this.pendingForms.set(formMessage.id, {
467
735
  toolName: toolInfo.toolName,
468
736
  originalInput: inputs,
469
- schema: toolInfo.schema
737
+ schema: toolInfo.schema,
470
738
  });
471
739
 
472
740
  globalPendingForms.set(formMessage.id, {
473
741
  toolName: toolInfo.toolName,
474
742
  originalInput: inputs,
475
- schema: toolInfo.schema
743
+ schema: toolInfo.schema,
476
744
  });
477
745
 
478
746
  return {
479
747
  output: this.formatFormResponse(formMessage),
480
748
  formMessage,
481
749
  requiresForm: true,
482
- intermediateSteps: intermediateSteps || []
750
+ intermediateSteps: intermediateSteps || [],
483
751
  };
484
752
  }
485
753
 
@@ -502,11 +770,16 @@ export class FormAwareAgentExecutor extends AgentExecutor {
502
770
  /**
503
771
  * Processes form submission and continues tool execution
504
772
  */
505
- async processFormSubmission(submission: FormSubmission): Promise<Record<string, unknown>> {
506
- this.formLogger.info('🚀 FormAwareAgentExecutor.processFormSubmission called!', {
507
- submissionFormId: submission.formId,
508
- submissionToolName: submission.toolName
509
- });
773
+ async processFormSubmission(
774
+ submission: FormSubmission
775
+ ): Promise<Record<string, unknown>> {
776
+ this.formLogger.info(
777
+ '🚀 FormAwareAgentExecutor.processFormSubmission called!',
778
+ {
779
+ submissionFormId: submission.formId,
780
+ submissionToolName: submission.toolName,
781
+ }
782
+ );
510
783
  if (!submission) {
511
784
  throw new Error('Form submission is null or undefined');
512
785
  }
@@ -515,8 +788,19 @@ export class FormAwareAgentExecutor extends AgentExecutor {
515
788
  throw new Error('Form submission missing formId');
516
789
  }
517
790
 
518
- if (!submission.parameters || submission.parameters === null || typeof submission.parameters !== 'object' || Array.isArray(submission.parameters)) {
519
- throw new Error(`Form submission parameters are invalid: ${typeof submission.parameters}, isNull: ${submission.parameters === null}, isArray: ${Array.isArray(submission.parameters)}, parameters: ${JSON.stringify(submission.parameters)}`);
791
+ if (
792
+ !submission.parameters ||
793
+ submission.parameters === null ||
794
+ typeof submission.parameters !== 'object' ||
795
+ Array.isArray(submission.parameters)
796
+ ) {
797
+ throw new Error(
798
+ `Form submission parameters are invalid: ${typeof submission.parameters}, isNull: ${
799
+ submission.parameters === null
800
+ }, isArray: ${Array.isArray(
801
+ submission.parameters
802
+ )}, parameters: ${JSON.stringify(submission.parameters)}`
803
+ );
520
804
  }
521
805
 
522
806
  this.formLogger.info('Processing form submission:', {
@@ -541,41 +825,58 @@ export class FormAwareAgentExecutor extends AgentExecutor {
541
825
  this.pendingForms.delete(submission.formId);
542
826
  globalPendingForms.delete(submission.formId);
543
827
 
544
- const tool = pendingForm.toolRef || this.tools.find(t => t.name === pendingForm.toolName);
828
+ const tool =
829
+ pendingForm.toolRef ||
830
+ this.tools.find((t) => t.name === pendingForm.toolName);
545
831
  if (!tool) {
546
- throw new Error(`Tool not found for form submission: ${pendingForm.toolName}`);
832
+ throw new Error(
833
+ `Tool not found for form submission: ${pendingForm.toolName}`
834
+ );
547
835
  }
548
836
 
549
837
  let baseToolInput: Record<string, unknown> = {};
550
838
  try {
551
- if (pendingForm.originalToolInput && typeof pendingForm.originalToolInput === 'object') {
552
- baseToolInput = { ...(pendingForm.originalToolInput as Record<string, unknown>) };
839
+ if (
840
+ pendingForm.originalToolInput &&
841
+ typeof pendingForm.originalToolInput === 'object'
842
+ ) {
843
+ baseToolInput = {
844
+ ...(pendingForm.originalToolInput as Record<string, unknown>),
845
+ };
553
846
  }
554
847
  } catch (error) {
555
- this.formLogger.warn('Failed to extract base tool input, using empty object:', error);
848
+ this.formLogger.warn(
849
+ 'Failed to extract base tool input, using empty object:',
850
+ error
851
+ );
556
852
  baseToolInput = {};
557
853
  }
558
854
 
559
855
  let submissionData: Record<string, unknown> = {};
560
856
  try {
561
857
  if (submission.parameters && typeof submission.parameters === 'object') {
562
- submissionData = { ...(submission.parameters as Record<string, unknown>) };
858
+ submissionData = {
859
+ ...(submission.parameters as Record<string, unknown>),
860
+ };
563
861
  }
564
862
  } catch (error) {
565
- this.formLogger.warn('Failed to extract submission parameters, using empty object:', error);
863
+ this.formLogger.warn(
864
+ 'Failed to extract submission parameters, using empty object:',
865
+ error
866
+ );
566
867
  submissionData = {};
567
868
  }
568
869
 
569
870
  const mergedToolInput: Record<string, unknown> = {};
570
871
  try {
571
- Object.keys(baseToolInput).forEach(key => {
872
+ Object.keys(baseToolInput).forEach((key) => {
572
873
  const value = baseToolInput[key];
573
874
  if (value !== undefined && value !== null) {
574
875
  mergedToolInput[key] = value;
575
876
  }
576
877
  });
577
878
 
578
- Object.keys(submissionData).forEach(key => {
879
+ Object.keys(submissionData).forEach((key) => {
579
880
  const value = submissionData[key];
580
881
  if (value !== undefined && value !== null) {
581
882
  mergedToolInput[key] = value;
@@ -584,7 +885,6 @@ export class FormAwareAgentExecutor extends AgentExecutor {
584
885
 
585
886
  mergedToolInput.renderForm = false;
586
887
  mergedToolInput.__fromForm = true;
587
-
588
888
 
589
889
  this.formLogger.info('Successfully merged tool input:', {
590
890
  baseKeys: Object.keys(baseToolInput),
@@ -593,14 +893,24 @@ export class FormAwareAgentExecutor extends AgentExecutor {
593
893
  });
594
894
  } catch (error) {
595
895
  this.formLogger.error('Failed to merge tool input data:', error);
596
- throw new Error(`Failed to merge tool input data: ${error instanceof Error ? error.message : 'Unknown error'}`);
896
+ throw new Error(
897
+ `Failed to merge tool input data: ${
898
+ error instanceof Error ? error.message : 'Unknown error'
899
+ }`
900
+ );
597
901
  }
598
902
 
599
903
  try {
600
904
  const maybeWrapper = tool as unknown as {
601
905
  executeOriginal?: (args: Record<string, unknown>) => Promise<string>;
602
- getOriginalTool?: () => { _call?: (args: Record<string, unknown>) => Promise<string>; call?: (args: Record<string, unknown>) => Promise<string> };
603
- originalTool?: { _call?: (args: Record<string, unknown>) => Promise<string>; call?: (args: Record<string, unknown>) => Promise<string> };
906
+ getOriginalTool?: () => {
907
+ _call?: (args: Record<string, unknown>) => Promise<string>;
908
+ call?: (args: Record<string, unknown>) => Promise<string>;
909
+ };
910
+ originalTool?: {
911
+ _call?: (args: Record<string, unknown>) => Promise<string>;
912
+ call?: (args: Record<string, unknown>) => Promise<string>;
913
+ };
604
914
  call?: (args: Record<string, unknown>) => Promise<string>;
605
915
  };
606
916
  let toolOutput: string;
@@ -617,72 +927,116 @@ export class FormAwareAgentExecutor extends AgentExecutor {
617
927
  } else if (ot && typeof otCall.call === 'function') {
618
928
  toolOutput = await otCall.call(mergedToolInput);
619
929
  } else {
620
- const tcall = tool as unknown as { call?: (a: Record<string, unknown>) => Promise<string> };
930
+ const tcall = tool as unknown as {
931
+ call?: (a: Record<string, unknown>) => Promise<string>;
932
+ };
621
933
  if (typeof tcall.call === 'function') {
622
934
  toolOutput = await tcall.call(mergedToolInput);
623
935
  } else {
624
- throw new Error('No callable tool implementation found for form submission');
936
+ throw new Error(
937
+ 'No callable tool implementation found for form submission'
938
+ );
625
939
  }
626
940
  }
627
- } else if (maybeWrapper.originalTool && typeof maybeWrapper.originalTool._call === 'function') {
941
+ } else if (
942
+ maybeWrapper.originalTool &&
943
+ typeof maybeWrapper.originalTool._call === 'function'
944
+ ) {
628
945
  toolOutput = await maybeWrapper.originalTool._call(mergedToolInput);
629
- } else if (maybeWrapper.originalTool && typeof maybeWrapper.originalTool.call === 'function') {
946
+ } else if (
947
+ maybeWrapper.originalTool &&
948
+ typeof maybeWrapper.originalTool.call === 'function'
949
+ ) {
630
950
  toolOutput = await maybeWrapper.originalTool.call(mergedToolInput);
631
- } else if (typeof (tool as unknown as { call?: (a: Record<string, unknown>) => Promise<string> }).call === 'function') {
632
- toolOutput = await (tool as unknown as { call: (a: Record<string, unknown>) => Promise<string> }).call(mergedToolInput);
951
+ } else if (
952
+ typeof (
953
+ tool as unknown as {
954
+ call?: (a: Record<string, unknown>) => Promise<string>;
955
+ }
956
+ ).call === 'function'
957
+ ) {
958
+ toolOutput = await (
959
+ tool as unknown as {
960
+ call: (a: Record<string, unknown>) => Promise<string>;
961
+ }
962
+ ).call(mergedToolInput);
633
963
  } else {
634
- throw new Error('No callable tool implementation found for form submission');
964
+ throw new Error(
965
+ 'No callable tool implementation found for form submission'
966
+ );
635
967
  }
636
968
 
637
969
  let responseMetadata: Record<string, unknown> = {};
638
970
  let formattedOutput: string;
639
-
971
+
640
972
  this.formLogger.info('🔍 METADATA EXTRACTION: Analyzing tool output', {
641
973
  outputType: typeof toolOutput,
642
974
  outputLength: toolOutput?.length || 0,
643
975
  isString: typeof toolOutput === 'string',
644
- firstChars: typeof toolOutput === 'string' ? toolOutput.substring(0, 100) : 'not-string'
976
+ firstChars:
977
+ typeof toolOutput === 'string'
978
+ ? toolOutput.substring(0, 100)
979
+ : 'not-string',
645
980
  });
646
-
981
+
647
982
  try {
648
983
  const parsed = JSON.parse(toolOutput);
649
- this.formLogger.info('✅ METADATA EXTRACTION: Successfully parsed JSON', {
650
- jsonKeys: Object.keys(parsed),
651
- hasHashLinkBlock: !!(parsed as Record<string, unknown>).hashLinkBlock
652
- });
653
-
984
+ this.formLogger.info(
985
+ '✅ METADATA EXTRACTION: Successfully parsed JSON',
986
+ {
987
+ jsonKeys: Object.keys(parsed),
988
+ hasHashLinkBlock: !!(parsed as Record<string, unknown>)
989
+ .hashLinkBlock,
990
+ }
991
+ );
992
+
654
993
  if (parsed && typeof parsed === 'object') {
655
994
  if (ResponseFormatter.isHashLinkResponse(parsed)) {
656
- this.formLogger.info('🔗 HASHLINK DETECTED: Processing HashLink response separately to preserve metadata');
657
-
995
+ this.formLogger.info(
996
+ '🔗 HASHLINK DETECTED: Processing HashLink response separately to preserve metadata'
997
+ );
998
+
658
999
  responseMetadata = {
659
1000
  ...responseMetadata,
660
- hashLinkBlock: (parsed as Record<string, unknown>).hashLinkBlock
1001
+ hashLinkBlock: (parsed as Record<string, unknown>).hashLinkBlock,
661
1002
  };
662
-
1003
+
663
1004
  formattedOutput = ResponseFormatter.formatHashLinkResponse(parsed);
664
-
665
- this.formLogger.info('🔗 METADATA PRESERVED: HashLink metadata extracted for component rendering', {
666
- blockId: (responseMetadata.hashLinkBlock as any)?.blockId,
667
- hasTemplate: !!(responseMetadata.hashLinkBlock as any)?.template
668
- });
1005
+
1006
+ this.formLogger.info(
1007
+ '🔗 METADATA PRESERVED: HashLink metadata extracted for component rendering',
1008
+ {
1009
+ blockId: this.hasHashLinkBlock(responseMetadata)
1010
+ ? responseMetadata.hashLinkBlock.blockId
1011
+ : undefined,
1012
+ hasTemplate: this.hasHashLinkBlock(responseMetadata)
1013
+ ? !!responseMetadata.hashLinkBlock.template
1014
+ : false,
1015
+ }
1016
+ );
669
1017
  } else {
670
1018
  formattedOutput = ResponseFormatter.formatResponse(toolOutput);
671
-
1019
+
672
1020
  responseMetadata = {
673
1021
  ...responseMetadata,
674
- hashLinkBlock: (parsed as Record<string, unknown>).hashLinkBlock
1022
+ hashLinkBlock: (parsed as Record<string, unknown>).hashLinkBlock,
675
1023
  };
676
1024
  }
677
1025
  } else {
678
1026
  formattedOutput = ResponseFormatter.formatResponse(toolOutput);
679
1027
  }
680
1028
  } catch (error) {
681
- this.formLogger.warn('❌ METADATA EXTRACTION: Tool output is not JSON', {
682
- error: error instanceof Error ? error.message : 'unknown error',
683
- outputSample: typeof toolOutput === 'string' ? toolOutput.substring(0, 200) : 'not-string'
684
- });
685
-
1029
+ this.formLogger.warn(
1030
+ '❌ METADATA EXTRACTION: Tool output is not JSON',
1031
+ {
1032
+ error: error instanceof Error ? error.message : 'unknown error',
1033
+ outputSample:
1034
+ typeof toolOutput === 'string'
1035
+ ? toolOutput.substring(0, 200)
1036
+ : 'not-string',
1037
+ }
1038
+ );
1039
+
686
1040
  formattedOutput = ResponseFormatter.formatResponse(toolOutput);
687
1041
  }
688
1042
 
@@ -691,7 +1045,9 @@ export class FormAwareAgentExecutor extends AgentExecutor {
691
1045
  formCompleted: true,
692
1046
  originalFormId: submission.formId,
693
1047
  intermediateSteps: [],
694
- metadata: responseMetadata
1048
+ metadata: responseMetadata,
1049
+ rawToolOutput: toolOutput,
1050
+ toolName: pendingForm.toolName,
695
1051
  };
696
1052
  } catch (error) {
697
1053
  if (error instanceof ZodError) {
@@ -713,12 +1069,15 @@ export class FormAwareAgentExecutor extends AgentExecutor {
713
1069
  if (intermediateSteps.length > 0) {
714
1070
  const lastStep = intermediateSteps[intermediateSteps.length - 1];
715
1071
  if (lastStep.action && lastStep.action.tool) {
716
- const tool = this.tools.find(t => t.name === lastStep.action.tool);
1072
+ const tool = this.tools.find((t) => t.name === lastStep.action.tool);
717
1073
  if (tool && 'schema' in tool) {
718
- this.formLogger.info('Found tool from intermediate steps:', lastStep.action.tool);
1074
+ this.formLogger.info(
1075
+ 'Found tool from intermediate steps:',
1076
+ lastStep.action.tool
1077
+ );
719
1078
  return {
720
1079
  toolName: lastStep.action.tool,
721
- schema: (tool as unknown as Record<string, unknown>).schema
1080
+ schema: (tool as unknown as Record<string, unknown>).schema,
722
1081
  };
723
1082
  }
724
1083
  }
@@ -728,7 +1087,7 @@ export class FormAwareAgentExecutor extends AgentExecutor {
728
1087
  if (inputSteps.length > 0) {
729
1088
  const lastStep = inputSteps[inputSteps.length - 1];
730
1089
  let action: AgentAction;
731
-
1090
+
732
1091
  if (Array.isArray(lastStep) && lastStep.length > 0) {
733
1092
  action = lastStep[0] as AgentAction;
734
1093
  } else if ((lastStep as Record<string, unknown>).action) {
@@ -736,14 +1095,14 @@ export class FormAwareAgentExecutor extends AgentExecutor {
736
1095
  } else {
737
1096
  action = lastStep as AgentAction;
738
1097
  }
739
-
1098
+
740
1099
  if (action && action.tool) {
741
- const tool = this.tools.find(t => t.name === action.tool);
1100
+ const tool = this.tools.find((t) => t.name === action.tool);
742
1101
  if (tool && 'schema' in tool) {
743
1102
  this.formLogger.info('Found tool from input steps:', action.tool);
744
1103
  return {
745
1104
  toolName: action.tool,
746
- schema: (tool as unknown as Record<string, unknown>).schema
1105
+ schema: (tool as unknown as Record<string, unknown>).schema,
747
1106
  };
748
1107
  }
749
1108
  }
@@ -751,7 +1110,10 @@ export class FormAwareAgentExecutor extends AgentExecutor {
751
1110
 
752
1111
  const toolFromContext = this.findToolFromContext(inputs);
753
1112
  if (toolFromContext) {
754
- this.formLogger.info('Found tool from context:', toolFromContext.toolName);
1113
+ this.formLogger.info(
1114
+ 'Found tool from context:',
1115
+ toolFromContext.toolName
1116
+ );
755
1117
  return toolFromContext;
756
1118
  }
757
1119
 
@@ -765,22 +1127,24 @@ export class FormAwareAgentExecutor extends AgentExecutor {
765
1127
  /**
766
1128
  * Attempts to find tool from execution context
767
1129
  */
768
- private findToolFromContext(inputs: Record<string, unknown>): {
769
- toolName: string;
770
- schema: unknown
1130
+ private findToolFromContext(inputs: Record<string, unknown>): {
1131
+ toolName: string;
1132
+ schema: unknown;
771
1133
  } | null {
772
1134
  const inputText = (inputs.input as string) || '';
773
-
1135
+
774
1136
  for (const tool of this.tools) {
775
1137
  const keywords = this.extractToolKeywords(tool.name);
776
-
777
- if (keywords.some(keyword =>
778
- inputText.toLowerCase().includes(keyword.toLowerCase())
779
- )) {
1138
+
1139
+ if (
1140
+ keywords.some((keyword) =>
1141
+ inputText.toLowerCase().includes(keyword.toLowerCase())
1142
+ )
1143
+ ) {
780
1144
  if ('schema' in tool) {
781
1145
  return {
782
1146
  toolName: tool.name,
783
- schema: (tool as unknown as Record<string, unknown>).schema
1147
+ schema: (tool as unknown as Record<string, unknown>).schema,
784
1148
  };
785
1149
  }
786
1150
  }
@@ -795,16 +1159,19 @@ export class FormAwareAgentExecutor extends AgentExecutor {
795
1159
  private detectToolFromErrorContext(
796
1160
  error: ZodError
797
1161
  ): { toolName: string; schema: unknown } | null {
798
- const errorPaths = error.issues.map(issue => issue.path.join('.'));
799
-
1162
+ const errorPaths = error.issues.map((issue) => issue.path.join('.'));
1163
+
800
1164
  for (const tool of this.tools) {
801
1165
  if ('schema' in tool) {
802
1166
  const toolSchema = (tool as unknown as Record<string, unknown>).schema;
803
1167
  if (this.schemaMatchesErrorPaths(toolSchema, errorPaths)) {
804
- this.formLogger.info('Detected tool from error path analysis:', tool.name);
1168
+ this.formLogger.info(
1169
+ 'Detected tool from error path analysis:',
1170
+ tool.name
1171
+ );
805
1172
  return {
806
1173
  toolName: tool.name,
807
- schema: toolSchema
1174
+ schema: toolSchema,
808
1175
  };
809
1176
  }
810
1177
  }
@@ -816,16 +1183,19 @@ export class FormAwareAgentExecutor extends AgentExecutor {
816
1183
  /**
817
1184
  * Checks if a schema structure matches error paths
818
1185
  */
819
- private schemaMatchesErrorPaths(schema: unknown, errorPaths: string[]): boolean {
1186
+ private schemaMatchesErrorPaths(
1187
+ schema: unknown,
1188
+ errorPaths: string[]
1189
+ ): boolean {
820
1190
  const schemaRecord = schema as Record<string, unknown>;
821
1191
  if (!schemaRecord || !schemaRecord._def) return false;
822
-
1192
+
823
1193
  try {
824
1194
  const def = schemaRecord._def as Record<string, unknown>;
825
1195
  if (def.typeName === 'ZodObject') {
826
1196
  const shape = def.shape as Record<string, unknown>;
827
1197
  const schemaKeys = Object.keys(shape || {});
828
- return errorPaths.some(path => {
1198
+ return errorPaths.some((path) => {
829
1199
  const topLevelKey = path.split('.')[0];
830
1200
  return schemaKeys.includes(topLevelKey);
831
1201
  });
@@ -833,7 +1203,7 @@ export class FormAwareAgentExecutor extends AgentExecutor {
833
1203
  } catch (err) {
834
1204
  this.formLogger.debug('Error analyzing schema structure:', err);
835
1205
  }
836
-
1206
+
837
1207
  return false;
838
1208
  }
839
1209
 
@@ -845,8 +1215,8 @@ export class FormAwareAgentExecutor extends AgentExecutor {
845
1215
  .replace(/([A-Z])/g, ' $1')
846
1216
  .toLowerCase()
847
1217
  .split(/[\s_-]+/)
848
- .filter(w => w.length > 2);
849
-
1218
+ .filter((w) => w.length > 2);
1219
+
850
1220
  return [...words, toolName.toLowerCase()];
851
1221
  }
852
1222
 
@@ -857,7 +1227,7 @@ export class FormAwareAgentExecutor extends AgentExecutor {
857
1227
  const fieldCount = formMessage.formConfig.fields.length;
858
1228
  const fieldList = formMessage.formConfig.fields
859
1229
  .slice(0, 3)
860
- .map(f => `• ${f.label}`)
1230
+ .map((f) => `• ${f.label}`)
861
1231
  .join('\n');
862
1232
 
863
1233
  return `I need some additional information to complete your request.
@@ -883,78 +1253,89 @@ Please fill out the form below to continue.`;
883
1253
  getPendingFormsInfo(): Array<{ formId: string; toolName: string }> {
884
1254
  return Array.from(this.pendingForms.entries()).map(([formId, info]) => ({
885
1255
  formId,
886
- toolName: info.toolName
1256
+ toolName: info.toolName,
887
1257
  }));
888
1258
  }
889
1259
 
890
1260
  /**
891
1261
  * Processes HashLink block responses from tools
892
1262
  */
893
- private processHashLinkResponse(toolResponse: ToolResponse): HashLinkResponse {
1263
+ private processHashLinkResponse(
1264
+ toolResponse: ToolResponse
1265
+ ): HashLinkResponse {
894
1266
  try {
895
-
896
1267
  let hashLinkBlock: HashLinkBlock | undefined;
897
-
1268
+
898
1269
  if (toolResponse.hashLinkBlock) {
899
1270
  hashLinkBlock = toolResponse.hashLinkBlock;
900
- } else if (toolResponse.success && toolResponse.inscription && toolResponse.hashLinkBlock) {
1271
+ } else if (
1272
+ toolResponse.success &&
1273
+ toolResponse.inscription &&
1274
+ toolResponse.hashLinkBlock
1275
+ ) {
901
1276
  hashLinkBlock = toolResponse.hashLinkBlock;
902
1277
  }
903
-
1278
+
904
1279
  if (!hashLinkBlock) {
905
1280
  throw new Error('HashLink block data not found in response');
906
1281
  }
907
-
908
- if (!hashLinkBlock.blockId || !hashLinkBlock.hashLink || !hashLinkBlock.attributes) {
909
- throw new Error('Invalid HashLink block structure - missing required fields');
1282
+
1283
+ if (
1284
+ !hashLinkBlock.blockId ||
1285
+ !hashLinkBlock.hashLink ||
1286
+ !hashLinkBlock.attributes
1287
+ ) {
1288
+ throw new Error(
1289
+ 'Invalid HashLink block structure - missing required fields'
1290
+ );
910
1291
  }
911
-
1292
+
912
1293
  let message = 'Content processed successfully!';
913
-
1294
+
914
1295
  if (toolResponse.success && toolResponse.inscription) {
915
1296
  const inscription = toolResponse.inscription;
916
1297
  const metadata = toolResponse.metadata || {};
917
-
1298
+
918
1299
  message = `✅ ${inscription.standard} Hashinal inscription completed!\n\n`;
919
-
1300
+
920
1301
  if (metadata.name) {
921
1302
  message += `**${metadata.name}**\n`;
922
1303
  }
923
-
1304
+
924
1305
  if (metadata.description) {
925
1306
  message += `${metadata.description}\n\n`;
926
1307
  }
927
-
1308
+
928
1309
  message += `📍 **Topic ID:** ${inscription.topicId}\n`;
929
1310
  message += `🔗 **HRL:** ${inscription.hrl}\n`;
930
-
1311
+
931
1312
  if (inscription.cdnUrl) {
932
1313
  message += `🌐 **CDN URL:** ${inscription.cdnUrl}\n`;
933
1314
  }
934
-
1315
+
935
1316
  if (metadata.creator) {
936
1317
  message += `👤 **Creator:** ${metadata.creator}\n`;
937
1318
  }
938
1319
  }
939
-
1320
+
940
1321
  this.formLogger.info('Processed HashLink response', {
941
1322
  blockId: hashLinkBlock.blockId,
942
1323
  hashLink: hashLinkBlock.hashLink,
943
1324
  hasTemplate: !!hashLinkBlock.template,
944
- attributeCount: Object.keys(hashLinkBlock.attributes || {}).length
1325
+ attributeCount: Object.keys(hashLinkBlock.attributes || {}).length,
945
1326
  });
946
-
1327
+
947
1328
  return {
948
1329
  hasHashLinkBlocks: true,
949
1330
  hashLinkBlock,
950
- message
1331
+ message,
951
1332
  };
952
1333
  } catch (error) {
953
1334
  this.formLogger.error('Error processing HashLink response:', error);
954
-
1335
+
955
1336
  return {
956
1337
  hasHashLinkBlocks: false,
957
- message: 'Content processed, but interactive display is not available.'
1338
+ message: 'Content processed, but interactive display is not available.',
958
1339
  };
959
1340
  }
960
1341
  }
@@ -962,7 +1343,10 @@ Please fill out the form below to continue.`;
962
1343
  /**
963
1344
  * Get FormEngine statistics for debugging
964
1345
  */
965
- getFormEngineStatistics() {
1346
+ getFormEngineStatistics(): {
1347
+ strategies: string[];
1348
+ middleware: string[];
1349
+ } {
966
1350
  return {
967
1351
  strategies: this.formEngine.getRegisteredStrategies(),
968
1352
  middleware: this.formEngine.getRegisteredMiddleware(),