@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
@@ -1,308 +1,970 @@
1
- import { ZodError } from "zod";
1
+ import { AgentExecutor } from "langchain/agents";
2
+ import { z, ZodError } from "zod";
3
+ import { FormGenerator } from "./index10.js";
4
+ import { FormEngine } from "./index11.js";
2
5
  import { Logger } from "@hashgraphonline/standards-sdk";
3
- import { FormGenerator } from "./index18.js";
4
6
  import { isFormValidatable } from "@hashgraphonline/standards-agent-kit";
5
- class FormEngine {
6
- constructor(logger) {
7
+ import { ResponseFormatter } from "./index33.js";
8
+ const globalPendingForms = /* @__PURE__ */ new Map();
9
+ class FormAwareAgentExecutor extends AgentExecutor {
10
+ constructor(...args) {
11
+ super(...args);
12
+ this.pendingForms = /* @__PURE__ */ new Map();
7
13
  this.formGenerator = new FormGenerator();
8
- this.logger = logger || new Logger({ module: "FormEngine" });
14
+ this.formEngine = new FormEngine(
15
+ new Logger({ module: "FormAwareAgentExecutor.FormEngine" })
16
+ );
17
+ this.formLogger = new Logger({ module: "FormAwareAgentExecutor" });
18
+ this.parameterPreprocessingCallback = void 0;
9
19
  }
10
20
  /**
11
- * Generate a form for a tool with the given input
21
+ * Type guard to check if a Zod type is a ZodObject
12
22
  */
13
- async generateForm(toolName, tool, input, context) {
14
- const fullContext = {
15
- tool,
16
- input,
17
- ...context
18
- };
19
- try {
20
- if (isFormValidatable(tool)) {
21
- return await this.generateFormValidatableForm(tool, input, fullContext);
22
- }
23
- if (input instanceof ZodError) {
24
- return await this.generateErrorBasedForm(tool, input, fullContext);
25
- }
26
- if (this.hasRenderConfig(tool)) {
27
- return await this.generateRenderConfigForm(tool, input, fullContext);
28
- }
29
- if (this.isZodObject(tool.schema)) {
30
- return await this.generateSchemaBasedForm(tool, input, fullContext);
31
- }
32
- return null;
33
- } catch (error) {
34
- this.logger.error(`Failed to generate form for tool: ${toolName}`, {
35
- error: error instanceof Error ? error.message : String(error)
36
- });
37
- throw error;
38
- }
23
+ isZodObject(schema) {
24
+ return schema instanceof z.ZodObject;
39
25
  }
40
26
  /**
41
- * Process a form submission
27
+ * Type guard to check if metadata has hashLinkBlock
42
28
  */
43
- async processSubmission(submission, context) {
44
- this.validateSubmission(submission);
45
- const baseToolInput = this.extractBaseToolInput(context);
46
- const submissionData = this.extractSubmissionData(submission);
47
- return this.mergeInputData(baseToolInput, submissionData);
29
+ hasHashLinkBlock(metadata) {
30
+ return typeof metadata === "object" && metadata !== null && "hashLinkBlock" in metadata && typeof metadata.hashLinkBlock === "object" && metadata.hashLinkBlock !== null;
48
31
  }
49
32
  /**
50
- * Check if a tool requires form generation based on input
33
+ * Set parameter preprocessing callback
51
34
  */
52
- shouldGenerateForm(tool, input) {
53
- const inputRecord = input;
54
- if (inputRecord?.__fromForm === true || inputRecord?.renderForm === false) {
55
- return false;
35
+ setParameterPreprocessingCallback(callback) {
36
+ this.parameterPreprocessingCallback = callback;
37
+ }
38
+ /**
39
+ * BULLETPROOF TOOL INTERCEPTION
40
+ * Override the single-step execution to intercept tool calls BEFORE LangChain processes them
41
+ */
42
+ async _takeNextStep(nameToolMap, inputs, intermediateSteps, runManager, config) {
43
+ this.formLogger.info("🛡️ BULLETPROOF INTERCEPTION: _takeNextStep called", {
44
+ availableTools: Object.keys(nameToolMap),
45
+ inputKeys: Object.keys(inputs)
46
+ });
47
+ const result = await this.agent.plan(
48
+ intermediateSteps,
49
+ inputs,
50
+ runManager?.getChild()
51
+ );
52
+ if ("returnValues" in result) {
53
+ this.formLogger.info("Agent returned finish action, passing through");
54
+ return result;
55
+ }
56
+ const action = result;
57
+ const toolName = action.tool;
58
+ const toolInput = action.toolInput;
59
+ this.formLogger.info(`🎯 INTERCEPTING TOOL CALL: ${toolName}`, {
60
+ toolInput,
61
+ hasInNameToolMap: toolName in nameToolMap,
62
+ toolInputKeys: Object.keys(toolInput || {})
63
+ });
64
+ const tool = nameToolMap[toolName] || this.tools.find((t) => t.name === toolName);
65
+ if (!tool) {
66
+ this.formLogger.error(`Tool ${toolName} not found in registry`);
67
+ throw new Error(`Tool "${toolName}" not found`);
56
68
  }
69
+ let shouldGenerateForm = false;
57
70
  if (isFormValidatable(tool)) {
71
+ this.formLogger.info(
72
+ `🔍 Tool ${toolName} implements FormValidatable, checking shouldGenerateForm()`,
73
+ {
74
+ toolInput
75
+ }
76
+ );
58
77
  try {
59
- const formValidatableTool = tool;
60
- return formValidatableTool.shouldGenerateForm(input);
78
+ shouldGenerateForm = tool.shouldGenerateForm(toolInput);
79
+ this.formLogger.info(
80
+ `FormValidatable.shouldGenerateForm() result: ${shouldGenerateForm}`,
81
+ {
82
+ toolName,
83
+ toolInput
84
+ }
85
+ );
61
86
  } catch (error) {
62
- this.logger.error(`Error calling shouldGenerateForm() on ${tool.name}:`, error);
63
- return false;
87
+ this.formLogger.error(
88
+ `Error calling shouldGenerateForm() on ${toolName}:`,
89
+ error
90
+ );
91
+ shouldGenerateForm = false;
92
+ }
93
+ }
94
+ if (shouldGenerateForm) {
95
+ this.formLogger.info(`🚨 FORM GENERATION TRIGGERED for ${toolName}`);
96
+ try {
97
+ let schemaToUse;
98
+ let isFocusedSchema = false;
99
+ if (isFormValidatable(tool)) {
100
+ this.formLogger.info(
101
+ `🎯 Tool ${toolName} is FormValidatable, attempting to get focused schema`
102
+ );
103
+ try {
104
+ const focusedSchema = tool.getFormSchema();
105
+ if (focusedSchema) {
106
+ schemaToUse = focusedSchema;
107
+ isFocusedSchema = true;
108
+ this.formLogger.info(
109
+ `✅ Successfully obtained focused schema for ${toolName}`
110
+ );
111
+ } else {
112
+ this.formLogger.warn(
113
+ `getFormSchema() returned null/undefined for ${toolName}, using default schema`
114
+ );
115
+ schemaToUse = tool.schema;
116
+ isFocusedSchema = false;
117
+ }
118
+ } catch (error) {
119
+ this.formLogger.error(
120
+ `Failed to get focused schema from ${toolName}:`,
121
+ error
122
+ );
123
+ this.formLogger.info(
124
+ `Falling back to default schema for ${toolName}`
125
+ );
126
+ schemaToUse = tool.schema;
127
+ isFocusedSchema = false;
128
+ }
129
+ } else {
130
+ this.formLogger.info(
131
+ `Tool ${toolName} is not FormValidatable, using default schema`
132
+ );
133
+ schemaToUse = tool.schema;
134
+ isFocusedSchema = false;
135
+ }
136
+ let schemaFieldCount = "unknown";
137
+ try {
138
+ if (this.isZodObject(schemaToUse)) {
139
+ const zodObject = schemaToUse;
140
+ const shape = zodObject.shape;
141
+ if (shape && typeof shape === "object") {
142
+ schemaFieldCount = Object.keys(shape).length.toString();
143
+ }
144
+ }
145
+ } catch {
146
+ }
147
+ this.formLogger.info(
148
+ `📋 Generating form with ${isFocusedSchema ? "FOCUSED" : "DEFAULT"} schema`,
149
+ {
150
+ toolName,
151
+ schemaType: schemaToUse?.constructor?.name,
152
+ estimatedFieldCount: schemaFieldCount,
153
+ isFocusedSchema
154
+ }
155
+ );
156
+ let missingFields;
157
+ if (isFocusedSchema) {
158
+ this.formLogger.info(
159
+ `⭐ Using focused schema - letting FormGenerator determine fields from schema`
160
+ );
161
+ missingFields = void 0;
162
+ } else {
163
+ missingFields = /* @__PURE__ */ new Set();
164
+ if (this.isZodObject(schemaToUse)) {
165
+ const zodObject = schemaToUse;
166
+ const shape = zodObject.shape || {};
167
+ for (const fieldName of Object.keys(shape)) {
168
+ const value = (toolInput || {})[fieldName];
169
+ const isEmpty = isFormValidatable(tool) && tool.isFieldEmpty ? tool.isFieldEmpty(fieldName, value) : value === void 0 || value === "" || value === null || Array.isArray(value) && value.length === 0;
170
+ const isRequired = this.isFieldRequired(schemaToUse, fieldName);
171
+ const isEssential = isFormValidatable(tool) && tool.getEssentialFields ? tool.getEssentialFields().includes(fieldName) : false;
172
+ this.formLogger.info(`🔍 Field analysis: ${fieldName}`, {
173
+ value,
174
+ isEmpty,
175
+ isRequired,
176
+ isEssential,
177
+ willAddToMissingFields: isEmpty && (isRequired || isEssential)
178
+ });
179
+ if (isEmpty && (isRequired || isEssential)) {
180
+ missingFields.add(fieldName);
181
+ }
182
+ }
183
+ }
184
+ this.formLogger.info(`📋 Missing fields analysis complete`, {
185
+ totalFields: this.isZodObject(schemaToUse) ? Object.keys(schemaToUse.shape).length : 0,
186
+ missingFieldsCount: missingFields.size,
187
+ missingFields: Array.from(missingFields)
188
+ });
189
+ }
190
+ const formMessage = await this.formGenerator.generateFormFromSchema(
191
+ schemaToUse,
192
+ toolInput,
193
+ {
194
+ toolName,
195
+ toolDescription: tool.description
196
+ },
197
+ missingFields
198
+ // Pass undefined for focused schemas, Set<string> for others
199
+ );
200
+ if (this.isZodObject(schemaToUse)) {
201
+ try {
202
+ const { jsonSchema, uiSchema } = this.formGenerator.generateJsonSchemaForm(
203
+ schemaToUse,
204
+ toolInput,
205
+ missingFields
206
+ );
207
+ formMessage.jsonSchema = jsonSchema;
208
+ formMessage.uiSchema = uiSchema;
209
+ } catch (error) {
210
+ this.formLogger.warn(
211
+ "Failed to generate JSON Schema for RJSF:",
212
+ error
213
+ );
214
+ }
215
+ }
216
+ formMessage.partialInput = toolInput;
217
+ const formData = {
218
+ toolName,
219
+ originalInput: inputs,
220
+ originalToolInput: toolInput,
221
+ schema: schemaToUse,
222
+ toolRef: tool,
223
+ originalToolRef: tool.originalTool
224
+ };
225
+ this.pendingForms.set(formMessage.id, formData);
226
+ globalPendingForms.set(formMessage.id, formData);
227
+ this.formLogger.info(`✅ FORM INTERCEPT SUCCESS for ${toolName}`);
228
+ const formResult = {
229
+ requiresForm: true,
230
+ formMessage
231
+ };
232
+ return [
233
+ {
234
+ action,
235
+ observation: JSON.stringify(formResult)
236
+ }
237
+ ];
238
+ } catch (error) {
239
+ this.formLogger.error(`Form generation failed for ${toolName}:`, error);
64
240
  }
65
241
  }
66
- const validation = this.validateInput(tool, input);
67
- return !validation.isValid;
242
+ this.formLogger.info(
243
+ `⚪ Passing through to normal tool execution for ${toolName}`
244
+ );
245
+ if (this.parameterPreprocessingCallback && toolInput) {
246
+ this.formLogger.info(
247
+ `🔄 Applying parameter preprocessing for ${toolName}`
248
+ );
249
+ try {
250
+ const preprocessedInput = await this.parameterPreprocessingCallback(
251
+ toolName,
252
+ toolInput
253
+ );
254
+ if (preprocessedInput && typeof preprocessedInput === "object" && "__requestForm" in preprocessedInput) {
255
+ const rf = preprocessedInput.__requestForm;
256
+ const formId = rf.id || `form_${Date.now()}_${Math.random().toString(36).slice(2)}`;
257
+ const formMessage = {
258
+ type: "form",
259
+ id: formId,
260
+ originalPrompt: "Parameter validation required",
261
+ toolName,
262
+ formConfig: {
263
+ title: rf.title || "Complete required parameters",
264
+ description: rf.description || "One or more parameters require confirmation. Please review and submit.",
265
+ submitLabel: rf.submitLabel || "Continue",
266
+ fields: (rf.fields || []).map((f) => {
267
+ const allowedTypes = [
268
+ "text",
269
+ "number",
270
+ "select",
271
+ "checkbox",
272
+ "textarea"
273
+ ];
274
+ const resolvedType = allowedTypes.includes(
275
+ f.type
276
+ ) ? f.type : "text";
277
+ return {
278
+ name: f.name,
279
+ label: f.label,
280
+ type: resolvedType,
281
+ required: f.required ?? true,
282
+ options: f.options
283
+ };
284
+ })
285
+ }
286
+ };
287
+ const resolvedSchema = isFormValidatable(tool) ? (() => {
288
+ try {
289
+ const s = tool.getFormSchema();
290
+ return s || tool.schema;
291
+ } catch {
292
+ return tool.schema;
293
+ }
294
+ })() : tool.schema;
295
+ this.pendingForms.set(formId, {
296
+ toolName,
297
+ originalInput: inputs,
298
+ originalToolInput: toolInput,
299
+ schema: resolvedSchema,
300
+ toolRef: tool,
301
+ originalToolRef: tool.originalTool
302
+ });
303
+ globalPendingForms.set(formId, {
304
+ toolName,
305
+ originalInput: inputs,
306
+ originalToolInput: toolInput,
307
+ schema: resolvedSchema
308
+ });
309
+ return [
310
+ {
311
+ action,
312
+ observation: JSON.stringify({ requiresForm: true, formMessage })
313
+ }
314
+ ];
315
+ }
316
+ if (JSON.stringify(preprocessedInput) !== JSON.stringify(toolInput)) {
317
+ this.formLogger.info(`📝 Parameters preprocessed for ${toolName}:`, {
318
+ original: Object.keys(toolInput),
319
+ preprocessed: Object.keys(preprocessedInput),
320
+ hasChanges: true
321
+ });
322
+ try {
323
+ action.toolInput = preprocessedInput;
324
+ } catch {
325
+ }
326
+ } else {
327
+ this.formLogger.debug(`No parameter changes needed for ${toolName}`);
328
+ }
329
+ } catch (preprocessError) {
330
+ this.formLogger.warn(
331
+ `Parameter preprocessing failed for ${toolName}, using original parameters:`,
332
+ preprocessError
333
+ );
334
+ }
335
+ }
336
+ return super._takeNextStep(
337
+ nameToolMap,
338
+ inputs,
339
+ intermediateSteps,
340
+ runManager,
341
+ config
342
+ );
68
343
  }
69
344
  /**
70
- * Generate form from error context
345
+ * Helper to determine if a field is required in the schema
71
346
  */
72
- async generateFormFromError(error, toolName, toolSchema, originalPrompt) {
73
- return this.formGenerator.generateFormFromError(
74
- error,
75
- toolSchema,
76
- toolName,
77
- originalPrompt
78
- );
347
+ isFieldRequired(schema, fieldPath) {
348
+ if (!schema || !fieldPath) {
349
+ return false;
350
+ }
351
+ try {
352
+ const obj = schema;
353
+ const def = obj._def;
354
+ if (!def || def.typeName !== "ZodObject") {
355
+ return false;
356
+ }
357
+ const rawShape = typeof def.shape === "function" ? def.shape() : def.shape;
358
+ if (!rawShape || typeof rawShape !== "object") {
359
+ return false;
360
+ }
361
+ const shape = rawShape;
362
+ const fieldSchema = shape[fieldPath];
363
+ if (!fieldSchema) {
364
+ return false;
365
+ }
366
+ const unwrapOptional = (s) => {
367
+ const inner = s._def;
368
+ if (inner && inner.typeName === "ZodOptional" && inner.innerType) {
369
+ return inner.innerType;
370
+ }
371
+ return s;
372
+ };
373
+ const unwrapped = unwrapOptional(fieldSchema);
374
+ const fdef = unwrapped._def;
375
+ if (!fdef) {
376
+ return true;
377
+ }
378
+ if (fdef.typeName === "ZodOptional" || fdef.typeName === "ZodDefault") {
379
+ return false;
380
+ }
381
+ if (fdef.defaultValue !== void 0) {
382
+ return false;
383
+ }
384
+ return true;
385
+ } catch (error) {
386
+ this.formLogger.debug(
387
+ `Could not determine if field ${fieldPath} is required:`,
388
+ error
389
+ );
390
+ }
391
+ return false;
79
392
  }
80
393
  /**
81
- * Generate form for FormValidatable tools
394
+ * Override _call to intercept Zod validation errors at the execution level
82
395
  */
83
- async generateFormValidatableForm(tool, input, _context) {
84
- const { schemaToUse, isFocusedSchema } = this.resolveFormSchema(tool);
85
- const missingFields = this.determineMissingFields(tool, input, schemaToUse, isFocusedSchema);
86
- return this.generateFormWithSchema(tool, input, schemaToUse, missingFields);
396
+ async _call(inputs) {
397
+ try {
398
+ const result = await super._call(inputs);
399
+ if (result.intermediateSteps && Array.isArray(result.intermediateSteps)) {
400
+ for (const step of result.intermediateSteps) {
401
+ if (step.observation) {
402
+ try {
403
+ const parsed = typeof step.observation === "string" ? JSON.parse(step.observation) : step.observation;
404
+ if (parsed.requiresForm && parsed.formMessage) {
405
+ this.formLogger.info("Tool requested form generation", {
406
+ toolName: step.action?.tool,
407
+ hasForm: true
408
+ });
409
+ const actionToolName = step.action?.tool || "unknown";
410
+ const toolInstance = this.tools.find(
411
+ (t) => t.name === actionToolName
412
+ );
413
+ const originalToolCandidate = toolInstance || {};
414
+ const pf = {
415
+ toolName: actionToolName,
416
+ originalInput: inputs,
417
+ originalToolInput: step.action?.toolInput,
418
+ schema: null,
419
+ toolRef: toolInstance,
420
+ originalToolRef: originalToolCandidate?.originalTool
421
+ };
422
+ this.pendingForms.set(parsed.formMessage.id, pf);
423
+ globalPendingForms.set(parsed.formMessage.id, pf);
424
+ return {
425
+ ...result,
426
+ requiresForm: true,
427
+ formMessage: parsed.formMessage,
428
+ output: parsed.message || "Please complete the form to continue."
429
+ };
430
+ }
431
+ if (parsed.hashLinkBlock || parsed.success && parsed.inscription && parsed.hashLinkBlock) {
432
+ this.formLogger.info("Tool returned HashLink blocks", {
433
+ toolName: step.action?.tool,
434
+ hasHashLink: true,
435
+ blockId: parsed.hashLinkBlock?.blockId
436
+ });
437
+ const hashLinkResponse = this.processHashLinkResponse(parsed);
438
+ return {
439
+ ...result,
440
+ hasHashLinkBlocks: true,
441
+ hashLinkBlock: hashLinkResponse.hashLinkBlock,
442
+ output: hashLinkResponse.message
443
+ };
444
+ }
445
+ } catch {
446
+ }
447
+ }
448
+ }
449
+ }
450
+ return result;
451
+ } catch (error) {
452
+ if (error instanceof ZodError) {
453
+ this.formLogger.info("Intercepted ZodError during agent execution");
454
+ return this.handleValidationError(error, inputs, []);
455
+ }
456
+ throw error;
457
+ }
87
458
  }
88
459
  /**
89
- * Generate form based on schema validation
460
+ * Handles Zod validation errors by generating forms
90
461
  */
91
- async generateSchemaBasedForm(tool, input, context) {
92
- const schema = tool.schema;
93
- const formMessage = await this.formGenerator.generateFormFromSchema(
94
- schema,
95
- input,
96
- {
97
- toolName: tool.name,
98
- toolDescription: tool.description
99
- },
100
- context.missingFields
462
+ async handleValidationError(error, inputs, intermediateSteps) {
463
+ this.formLogger.info("Zod validation error detected, generating form", {
464
+ errorIssues: error.issues.length,
465
+ inputKeys: Object.keys(inputs)
466
+ });
467
+ let toolInfo = this.extractToolInfoFromError(
468
+ error,
469
+ inputs,
470
+ intermediateSteps
101
471
  );
102
- if (this.isZodObject(schema)) {
103
- try {
104
- const { jsonSchema, uiSchema } = this.formGenerator.generateJsonSchemaForm(
105
- schema,
106
- input,
107
- context.missingFields || /* @__PURE__ */ new Set()
472
+ if (!toolInfo) {
473
+ this.formLogger.warn(
474
+ "Could not extract tool info from validation error, trying fallback detection"
475
+ );
476
+ const fallbackTool = this.detectToolFromErrorContext(error);
477
+ if (!fallbackTool) {
478
+ this.formLogger.error(
479
+ "No tool detected for form generation, rethrowing error"
108
480
  );
109
- formMessage.jsonSchema = jsonSchema;
110
- formMessage.uiSchema = uiSchema;
111
- } catch (error) {
112
- this.logger.warn("Failed to generate JSON Schema for schema-based tool:", error);
481
+ throw error;
113
482
  }
483
+ toolInfo = fallbackTool;
114
484
  }
115
- formMessage.partialInput = input;
116
- return formMessage;
485
+ this.formLogger.info("Generating form for tool:", {
486
+ toolName: toolInfo.toolName,
487
+ hasSchema: !!toolInfo.schema
488
+ });
489
+ const formMessage = this.formGenerator.generateFormFromError(
490
+ error,
491
+ toolInfo.schema,
492
+ toolInfo.toolName,
493
+ inputs.input || ""
494
+ );
495
+ this.pendingForms.set(formMessage.id, {
496
+ toolName: toolInfo.toolName,
497
+ originalInput: inputs,
498
+ schema: toolInfo.schema
499
+ });
500
+ globalPendingForms.set(formMessage.id, {
501
+ toolName: toolInfo.toolName,
502
+ originalInput: inputs,
503
+ schema: toolInfo.schema
504
+ });
505
+ return {
506
+ output: this.formatFormResponse(formMessage),
507
+ formMessage,
508
+ requiresForm: true,
509
+ intermediateSteps: intermediateSteps || []
510
+ };
117
511
  }
118
512
  /**
119
- * Generate form based on render config
513
+ * Get a copy of pending forms for preservation during executor recreation
120
514
  */
121
- async generateRenderConfigForm(tool, input, context) {
122
- const schema = tool.schema;
123
- const renderConfig = this.extractRenderConfig(tool);
124
- const formMessage = await this.formGenerator.generateFormFromSchema(
125
- schema,
126
- input,
127
- {
128
- toolName: tool.name,
129
- toolDescription: tool.description
130
- },
131
- context.missingFields
132
- );
133
- if (renderConfig) {
134
- formMessage.formConfig.metadata = {
135
- ...formMessage.formConfig.metadata,
136
- renderConfig
137
- };
138
- }
139
- formMessage.partialInput = input;
140
- return formMessage;
515
+ getPendingForms() {
516
+ return new Map(this.pendingForms);
141
517
  }
142
518
  /**
143
- * Generate form from Zod validation error
519
+ * Restore pending forms from a previous executor instance
144
520
  */
145
- async generateErrorBasedForm(tool, error, context) {
146
- return this.formGenerator.generateFormFromError(
147
- error,
148
- tool.schema,
149
- tool.name,
150
- context.input ? String(context.input) : ""
151
- );
521
+ restorePendingForms(forms) {
522
+ for (const [formId, formData] of forms) {
523
+ this.pendingForms.set(formId, formData);
524
+ }
152
525
  }
153
526
  /**
154
- * Validate input against tool schema
527
+ * Processes form submission and continues tool execution
155
528
  */
156
- validateInput(tool, input) {
529
+ async processFormSubmission(submission) {
530
+ this.formLogger.info(
531
+ "🚀 FormAwareAgentExecutor.processFormSubmission called!",
532
+ {
533
+ submissionFormId: submission.formId,
534
+ submissionToolName: submission.toolName
535
+ }
536
+ );
537
+ if (!submission) {
538
+ throw new Error("Form submission is null or undefined");
539
+ }
540
+ if (!submission.formId) {
541
+ throw new Error("Form submission missing formId");
542
+ }
543
+ if (!submission.parameters || submission.parameters === null || typeof submission.parameters !== "object" || Array.isArray(submission.parameters)) {
544
+ throw new Error(
545
+ `Form submission parameters are invalid: ${typeof submission.parameters}, isNull: ${submission.parameters === null}, isArray: ${Array.isArray(
546
+ submission.parameters
547
+ )}, parameters: ${JSON.stringify(submission.parameters)}`
548
+ );
549
+ }
550
+ this.formLogger.info("Processing form submission:", {
551
+ formId: submission.formId,
552
+ toolName: submission.toolName,
553
+ parameterKeys: Object.keys(submission.parameters),
554
+ parametersType: typeof submission.parameters,
555
+ parametersIsNull: submission.parameters === null,
556
+ parametersIsUndefined: submission.parameters === void 0,
557
+ hasContext: !!submission.context
558
+ });
559
+ let pendingForm = this.pendingForms.get(submission.formId);
560
+ if (!pendingForm) {
561
+ pendingForm = globalPendingForms.get(submission.formId);
562
+ if (!pendingForm) {
563
+ throw new Error(`No pending form found for ID: ${submission.formId}`);
564
+ }
565
+ }
566
+ this.pendingForms.delete(submission.formId);
567
+ globalPendingForms.delete(submission.formId);
568
+ const tool = pendingForm.toolRef || this.tools.find((t) => t.name === pendingForm.toolName);
569
+ if (!tool) {
570
+ throw new Error(
571
+ `Tool not found for form submission: ${pendingForm.toolName}`
572
+ );
573
+ }
574
+ let baseToolInput = {};
157
575
  try {
158
- const zodSchema = tool.schema;
159
- zodSchema.parse(input);
160
- return { isValid: true };
576
+ if (pendingForm.originalToolInput && typeof pendingForm.originalToolInput === "object") {
577
+ baseToolInput = {
578
+ ...pendingForm.originalToolInput
579
+ };
580
+ }
161
581
  } catch (error) {
162
- if (error instanceof ZodError) {
163
- const errors = error.errors.map(
164
- (err) => `${err.path.join(".")}: ${err.message}`
582
+ this.formLogger.warn(
583
+ "Failed to extract base tool input, using empty object:",
584
+ error
585
+ );
586
+ baseToolInput = {};
587
+ }
588
+ let submissionData = {};
589
+ try {
590
+ if (submission.parameters && typeof submission.parameters === "object") {
591
+ submissionData = {
592
+ ...submission.parameters
593
+ };
594
+ }
595
+ } catch (error) {
596
+ this.formLogger.warn(
597
+ "Failed to extract submission parameters, using empty object:",
598
+ error
599
+ );
600
+ submissionData = {};
601
+ }
602
+ const mergedToolInput = {};
603
+ try {
604
+ Object.keys(baseToolInput).forEach((key) => {
605
+ const value = baseToolInput[key];
606
+ if (value !== void 0 && value !== null) {
607
+ mergedToolInput[key] = value;
608
+ }
609
+ });
610
+ Object.keys(submissionData).forEach((key) => {
611
+ const value = submissionData[key];
612
+ if (value !== void 0 && value !== null) {
613
+ mergedToolInput[key] = value;
614
+ }
615
+ });
616
+ mergedToolInput.renderForm = false;
617
+ mergedToolInput.__fromForm = true;
618
+ this.formLogger.info("Successfully merged tool input:", {
619
+ baseKeys: Object.keys(baseToolInput),
620
+ submissionKeys: Object.keys(submissionData),
621
+ mergedKeys: Object.keys(mergedToolInput)
622
+ });
623
+ } catch (error) {
624
+ this.formLogger.error("Failed to merge tool input data:", error);
625
+ throw new Error(
626
+ `Failed to merge tool input data: ${error instanceof Error ? error.message : "Unknown error"}`
627
+ );
628
+ }
629
+ try {
630
+ const maybeWrapper = tool;
631
+ let toolOutput;
632
+ if (typeof maybeWrapper.executeOriginal === "function") {
633
+ toolOutput = await maybeWrapper.executeOriginal(mergedToolInput);
634
+ } else if (typeof maybeWrapper.getOriginalTool === "function") {
635
+ const ot = maybeWrapper.getOriginalTool();
636
+ const otCall = ot;
637
+ if (ot && typeof otCall._call === "function") {
638
+ toolOutput = await otCall._call(mergedToolInput);
639
+ } else if (ot && typeof otCall.call === "function") {
640
+ toolOutput = await otCall.call(mergedToolInput);
641
+ } else {
642
+ const tcall = tool;
643
+ if (typeof tcall.call === "function") {
644
+ toolOutput = await tcall.call(mergedToolInput);
645
+ } else {
646
+ throw new Error(
647
+ "No callable tool implementation found for form submission"
648
+ );
649
+ }
650
+ }
651
+ } else if (maybeWrapper.originalTool && typeof maybeWrapper.originalTool._call === "function") {
652
+ toolOutput = await maybeWrapper.originalTool._call(mergedToolInput);
653
+ } else if (maybeWrapper.originalTool && typeof maybeWrapper.originalTool.call === "function") {
654
+ toolOutput = await maybeWrapper.originalTool.call(mergedToolInput);
655
+ } else if (typeof tool.call === "function") {
656
+ toolOutput = await tool.call(mergedToolInput);
657
+ } else {
658
+ throw new Error(
659
+ "No callable tool implementation found for form submission"
165
660
  );
166
- return { isValid: false, errors };
167
661
  }
168
- return { isValid: false, errors: ["Validation failed"] };
662
+ let responseMetadata = {};
663
+ let formattedOutput;
664
+ this.formLogger.info("🔍 METADATA EXTRACTION: Analyzing tool output", {
665
+ outputType: typeof toolOutput,
666
+ outputLength: toolOutput?.length || 0,
667
+ isString: typeof toolOutput === "string",
668
+ firstChars: typeof toolOutput === "string" ? toolOutput.substring(0, 100) : "not-string"
669
+ });
670
+ try {
671
+ const parsed = JSON.parse(toolOutput);
672
+ this.formLogger.info(
673
+ "✅ METADATA EXTRACTION: Successfully parsed JSON",
674
+ {
675
+ jsonKeys: Object.keys(parsed),
676
+ hasHashLinkBlock: !!parsed.hashLinkBlock
677
+ }
678
+ );
679
+ if (parsed && typeof parsed === "object") {
680
+ if (ResponseFormatter.isHashLinkResponse(parsed)) {
681
+ this.formLogger.info(
682
+ "🔗 HASHLINK DETECTED: Processing HashLink response separately to preserve metadata"
683
+ );
684
+ responseMetadata = {
685
+ ...responseMetadata,
686
+ hashLinkBlock: parsed.hashLinkBlock
687
+ };
688
+ formattedOutput = ResponseFormatter.formatHashLinkResponse(parsed);
689
+ this.formLogger.info(
690
+ "🔗 METADATA PRESERVED: HashLink metadata extracted for component rendering",
691
+ {
692
+ blockId: this.hasHashLinkBlock(responseMetadata) ? responseMetadata.hashLinkBlock.blockId : void 0,
693
+ hasTemplate: this.hasHashLinkBlock(responseMetadata) ? !!responseMetadata.hashLinkBlock.template : false
694
+ }
695
+ );
696
+ } else {
697
+ formattedOutput = ResponseFormatter.formatResponse(toolOutput);
698
+ responseMetadata = {
699
+ ...responseMetadata,
700
+ hashLinkBlock: parsed.hashLinkBlock
701
+ };
702
+ }
703
+ } else {
704
+ formattedOutput = ResponseFormatter.formatResponse(toolOutput);
705
+ }
706
+ } catch (error) {
707
+ this.formLogger.warn(
708
+ "❌ METADATA EXTRACTION: Tool output is not JSON",
709
+ {
710
+ error: error instanceof Error ? error.message : "unknown error",
711
+ outputSample: typeof toolOutput === "string" ? toolOutput.substring(0, 200) : "not-string"
712
+ }
713
+ );
714
+ formattedOutput = ResponseFormatter.formatResponse(toolOutput);
715
+ }
716
+ return {
717
+ output: formattedOutput,
718
+ formCompleted: true,
719
+ originalFormId: submission.formId,
720
+ intermediateSteps: [],
721
+ metadata: responseMetadata,
722
+ rawToolOutput: toolOutput,
723
+ toolName: pendingForm.toolName
724
+ };
725
+ } catch (error) {
726
+ if (error instanceof ZodError) {
727
+ return this.handleValidationError(error, mergedToolInput, []);
728
+ }
729
+ throw error;
169
730
  }
170
731
  }
171
732
  /**
172
- * Check if schema is ZodObject
733
+ * Extracts tool information from the execution context
173
734
  */
174
- isZodObject(schema) {
175
- if (!schema || typeof schema !== "object") {
176
- return false;
735
+ extractToolInfoFromError(error, inputs, intermediateSteps) {
736
+ try {
737
+ if (intermediateSteps.length > 0) {
738
+ const lastStep = intermediateSteps[intermediateSteps.length - 1];
739
+ if (lastStep.action && lastStep.action.tool) {
740
+ const tool = this.tools.find((t) => t.name === lastStep.action.tool);
741
+ if (tool && "schema" in tool) {
742
+ this.formLogger.info(
743
+ "Found tool from intermediate steps:",
744
+ lastStep.action.tool
745
+ );
746
+ return {
747
+ toolName: lastStep.action.tool,
748
+ schema: tool.schema
749
+ };
750
+ }
751
+ }
752
+ }
753
+ const inputSteps = inputs.intermediateSteps || [];
754
+ if (inputSteps.length > 0) {
755
+ const lastStep = inputSteps[inputSteps.length - 1];
756
+ let action;
757
+ if (Array.isArray(lastStep) && lastStep.length > 0) {
758
+ action = lastStep[0];
759
+ } else if (lastStep.action) {
760
+ action = lastStep.action;
761
+ } else {
762
+ action = lastStep;
763
+ }
764
+ if (action && action.tool) {
765
+ const tool = this.tools.find((t) => t.name === action.tool);
766
+ if (tool && "schema" in tool) {
767
+ this.formLogger.info("Found tool from input steps:", action.tool);
768
+ return {
769
+ toolName: action.tool,
770
+ schema: tool.schema
771
+ };
772
+ }
773
+ }
774
+ }
775
+ const toolFromContext = this.findToolFromContext(inputs);
776
+ if (toolFromContext) {
777
+ this.formLogger.info(
778
+ "Found tool from context:",
779
+ toolFromContext.toolName
780
+ );
781
+ return toolFromContext;
782
+ }
783
+ return null;
784
+ } catch (err) {
785
+ this.formLogger.error("Error extracting tool info:", err);
786
+ return null;
177
787
  }
178
- const candidate = schema;
179
- return Boolean(candidate._def && candidate._def.typeName === "ZodObject");
180
- }
181
- /**
182
- * Check if tool has render configuration
183
- */
184
- hasRenderConfig(tool) {
185
- const schema = tool.schema;
186
- return !!(schema && schema._renderConfig);
187
- }
188
- /**
189
- * Extract render configuration from tool
190
- */
191
- extractRenderConfig(tool) {
192
- const schema = tool.schema;
193
- return schema?._renderConfig;
194
788
  }
195
789
  /**
196
- * Resolve form schema for FormValidatable tools
790
+ * Attempts to find tool from execution context
197
791
  */
198
- resolveFormSchema(tool) {
199
- const formValidatableTool = tool;
200
- if (formValidatableTool.getFormSchema) {
201
- const focusedSchema = formValidatableTool.getFormSchema();
202
- if (focusedSchema) {
203
- return { schemaToUse: focusedSchema, isFocusedSchema: true };
792
+ findToolFromContext(inputs) {
793
+ const inputText = inputs.input || "";
794
+ for (const tool of this.tools) {
795
+ const keywords = this.extractToolKeywords(tool.name);
796
+ if (keywords.some(
797
+ (keyword) => inputText.toLowerCase().includes(keyword.toLowerCase())
798
+ )) {
799
+ if ("schema" in tool) {
800
+ return {
801
+ toolName: tool.name,
802
+ schema: tool.schema
803
+ };
804
+ }
204
805
  }
205
806
  }
206
- return { schemaToUse: tool.schema, isFocusedSchema: false };
807
+ return null;
207
808
  }
208
809
  /**
209
- * Determine missing fields for form generation
810
+ * Additional fallback to detect tool from error context
210
811
  */
211
- determineMissingFields(tool, input, _schema, _isFocusedSchema) {
212
- const missingFields = /* @__PURE__ */ new Set();
213
- if (!input || typeof input !== "object") {
214
- return missingFields;
215
- }
216
- const inputRecord = input;
217
- const formValidatableTool = tool;
218
- if (formValidatableTool.getEssentialFields) {
219
- const essentialFields = formValidatableTool.getEssentialFields();
220
- for (const field of essentialFields) {
221
- if (!(field in inputRecord) || formValidatableTool.isFieldEmpty && formValidatableTool.isFieldEmpty(field, inputRecord[field])) {
222
- missingFields.add(field);
812
+ detectToolFromErrorContext(error) {
813
+ const errorPaths = error.issues.map((issue) => issue.path.join("."));
814
+ for (const tool of this.tools) {
815
+ if ("schema" in tool) {
816
+ const toolSchema = tool.schema;
817
+ if (this.schemaMatchesErrorPaths(toolSchema, errorPaths)) {
818
+ this.formLogger.info(
819
+ "Detected tool from error path analysis:",
820
+ tool.name
821
+ );
822
+ return {
823
+ toolName: tool.name,
824
+ schema: toolSchema
825
+ };
223
826
  }
224
827
  }
225
828
  }
226
- return missingFields;
829
+ return null;
227
830
  }
228
831
  /**
229
- * Generate form with resolved schema
832
+ * Checks if a schema structure matches error paths
230
833
  */
231
- async generateFormWithSchema(tool, input, schema, missingFields) {
232
- const formMessage = await this.formGenerator.generateFormFromSchema(
233
- schema,
234
- input,
235
- {
236
- toolName: tool.name,
237
- toolDescription: tool.description
238
- },
239
- missingFields
240
- );
241
- if (this.isZodObject(schema)) {
242
- try {
243
- const { jsonSchema, uiSchema } = this.formGenerator.generateJsonSchemaForm(
244
- schema,
245
- input,
246
- missingFields
247
- );
248
- formMessage.jsonSchema = jsonSchema;
249
- formMessage.uiSchema = uiSchema;
250
- } catch (error) {
251
- this.logger.warn("Failed to generate JSON Schema:", error);
834
+ schemaMatchesErrorPaths(schema, errorPaths) {
835
+ const schemaRecord = schema;
836
+ if (!schemaRecord || !schemaRecord._def) return false;
837
+ try {
838
+ const def = schemaRecord._def;
839
+ if (def.typeName === "ZodObject") {
840
+ const shape = def.shape;
841
+ const schemaKeys = Object.keys(shape || {});
842
+ return errorPaths.some((path) => {
843
+ const topLevelKey = path.split(".")[0];
844
+ return schemaKeys.includes(topLevelKey);
845
+ });
252
846
  }
847
+ } catch (err) {
848
+ this.formLogger.debug("Error analyzing schema structure:", err);
253
849
  }
254
- formMessage.partialInput = input;
255
- return formMessage;
850
+ return false;
256
851
  }
257
852
  /**
258
- * Validate form submission
853
+ * Extracts keywords from tool name for matching
259
854
  */
260
- validateSubmission(submission) {
261
- if (!submission.toolName) {
262
- throw new Error("Tool name is required in form submission");
263
- }
264
- if (!submission.parameters) {
265
- throw new Error("Parameters are required in form submission");
266
- }
855
+ extractToolKeywords(toolName) {
856
+ const words = toolName.replace(/([A-Z])/g, " $1").toLowerCase().split(/[\s_-]+/).filter((w) => w.length > 2);
857
+ return [...words, toolName.toLowerCase()];
267
858
  }
268
859
  /**
269
- * Extract base tool input from context
860
+ * Formats the form message for display
270
861
  */
271
- extractBaseToolInput(context) {
272
- return context?.originalInput || {};
862
+ formatFormResponse(formMessage) {
863
+ const fieldCount = formMessage.formConfig.fields.length;
864
+ const fieldList = formMessage.formConfig.fields.slice(0, 3).map((f) => `• ${f.label}`).join("\n");
865
+ return `I need some additional information to complete your request.
866
+
867
+ ${formMessage.formConfig.description}
868
+
869
+ Required fields:
870
+ ${fieldList}${fieldCount > 3 ? `
871
+ ... and ${fieldCount - 3} more` : ""}
872
+
873
+ Please fill out the form below to continue.`;
273
874
  }
274
875
  /**
275
- * Extract submission data
876
+ * Check if there are pending forms
276
877
  */
277
- extractSubmissionData(submission) {
278
- return {
279
- ...submission.parameters,
280
- __fromForm: true
281
- };
878
+ hasPendingForms() {
879
+ return this.pendingForms.size > 0;
282
880
  }
283
881
  /**
284
- * Merge input data
882
+ * Get information about pending forms
285
883
  */
286
- mergeInputData(baseInput, submissionData) {
287
- return {
288
- ...baseInput,
289
- ...submissionData
290
- };
884
+ getPendingFormsInfo() {
885
+ return Array.from(this.pendingForms.entries()).map(([formId, info]) => ({
886
+ formId,
887
+ toolName: info.toolName
888
+ }));
291
889
  }
292
890
  /**
293
- * Get registered strategies
891
+ * Processes HashLink block responses from tools
294
892
  */
295
- getRegisteredStrategies() {
296
- return ["FormValidatable", "SchemaBased", "RenderConfig", "ZodErrorBased"];
893
+ processHashLinkResponse(toolResponse) {
894
+ try {
895
+ let hashLinkBlock;
896
+ if (toolResponse.hashLinkBlock) {
897
+ hashLinkBlock = toolResponse.hashLinkBlock;
898
+ } else if (toolResponse.success && toolResponse.inscription && toolResponse.hashLinkBlock) {
899
+ hashLinkBlock = toolResponse.hashLinkBlock;
900
+ }
901
+ if (!hashLinkBlock) {
902
+ throw new Error("HashLink block data not found in response");
903
+ }
904
+ if (!hashLinkBlock.blockId || !hashLinkBlock.hashLink || !hashLinkBlock.attributes) {
905
+ throw new Error(
906
+ "Invalid HashLink block structure - missing required fields"
907
+ );
908
+ }
909
+ let message = "Content processed successfully!";
910
+ if (toolResponse.success && toolResponse.inscription) {
911
+ const inscription = toolResponse.inscription;
912
+ const metadata = toolResponse.metadata || {};
913
+ message = `✅ ${inscription.standard} Hashinal inscription completed!
914
+
915
+ `;
916
+ if (metadata.name) {
917
+ message += `**${metadata.name}**
918
+ `;
919
+ }
920
+ if (metadata.description) {
921
+ message += `${metadata.description}
922
+
923
+ `;
924
+ }
925
+ message += `📍 **Topic ID:** ${inscription.topicId}
926
+ `;
927
+ message += `🔗 **HRL:** ${inscription.hrl}
928
+ `;
929
+ if (inscription.cdnUrl) {
930
+ message += `🌐 **CDN URL:** ${inscription.cdnUrl}
931
+ `;
932
+ }
933
+ if (metadata.creator) {
934
+ message += `👤 **Creator:** ${metadata.creator}
935
+ `;
936
+ }
937
+ }
938
+ this.formLogger.info("Processed HashLink response", {
939
+ blockId: hashLinkBlock.blockId,
940
+ hashLink: hashLinkBlock.hashLink,
941
+ hasTemplate: !!hashLinkBlock.template,
942
+ attributeCount: Object.keys(hashLinkBlock.attributes || {}).length
943
+ });
944
+ return {
945
+ hasHashLinkBlocks: true,
946
+ hashLinkBlock,
947
+ message
948
+ };
949
+ } catch (error) {
950
+ this.formLogger.error("Error processing HashLink response:", error);
951
+ return {
952
+ hasHashLinkBlocks: false,
953
+ message: "Content processed, but interactive display is not available."
954
+ };
955
+ }
297
956
  }
298
957
  /**
299
- * Get registered middleware
958
+ * Get FormEngine statistics for debugging
300
959
  */
301
- getRegisteredMiddleware() {
302
- return ["FormSubmissionValidator"];
960
+ getFormEngineStatistics() {
961
+ return {
962
+ strategies: this.formEngine.getRegisteredStrategies(),
963
+ middleware: this.formEngine.getRegisteredMiddleware()
964
+ };
303
965
  }
304
966
  }
305
967
  export {
306
- FormEngine
968
+ FormAwareAgentExecutor
307
969
  };
308
970
  //# sourceMappingURL=index29.js.map