@hashgraphonline/conversational-agent 0.1.217 → 0.1.218

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 (286) 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/cjs/core/{ToolRegistry.d.ts → tool-registry.d.ts} +10 -7
  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 -12
  19. package/dist/cjs/langchain/index.d.ts +2 -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 -16
  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 +811 -224
  86. package/dist/esm/index29.js.map +1 -1
  87. package/dist/esm/index30.js +1245 -122
  88. package/dist/esm/index30.js.map +1 -1
  89. package/dist/esm/index31.js +126 -56
  90. package/dist/esm/index31.js.map +1 -1
  91. package/dist/esm/index32.js +111 -24
  92. package/dist/esm/index32.js.map +1 -1
  93. package/dist/esm/index33.js +41 -87
  94. package/dist/esm/index33.js.map +1 -1
  95. package/dist/esm/index34.js +88 -227
  96. package/dist/esm/index34.js.map +1 -1
  97. package/dist/esm/index35.js +24 -0
  98. package/dist/esm/index35.js.map +1 -0
  99. package/dist/esm/index36.js +15 -0
  100. package/dist/esm/index36.js.map +1 -0
  101. package/dist/esm/index37.js +10 -0
  102. package/dist/esm/index37.js.map +1 -0
  103. package/dist/esm/index38.js +8 -0
  104. package/dist/esm/index38.js.map +1 -0
  105. package/dist/esm/index39.js +227 -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 +95 -0
  112. package/dist/esm/index42.js.map +1 -0
  113. package/dist/esm/index5.js +2 -2
  114. package/dist/esm/index5.js.map +1 -1
  115. package/dist/esm/index6.js +44 -67
  116. package/dist/esm/index6.js.map +1 -1
  117. package/dist/esm/index7.js +9 -0
  118. package/dist/esm/index7.js.map +1 -1
  119. package/dist/esm/index8.js +13 -1095
  120. package/dist/esm/index8.js.map +1 -1
  121. package/dist/esm/index9.js +17 -13
  122. package/dist/esm/index9.js.map +1 -1
  123. package/dist/types/constants/entity-references.d.ts +18 -0
  124. package/dist/types/constants/form-priorities.d.ts +24 -0
  125. package/dist/types/constants/index.d.ts +4 -0
  126. package/dist/types/constants/messages.d.ts +19 -0
  127. package/dist/types/constants/test-constants.d.ts +42 -0
  128. package/dist/types/conversational-agent.d.ts +3 -8
  129. package/dist/types/core/{ToolRegistry.d.ts → tool-registry.d.ts} +10 -7
  130. package/dist/{cjs/execution/ExecutionPipeline.d.ts → types/execution/execution-pipeline.d.ts} +3 -3
  131. package/dist/types/forms/field-guidance-registry.d.ts +108 -0
  132. package/dist/types/forms/form-generator.d.ts +2 -7
  133. package/dist/types/forms/index.d.ts +3 -0
  134. package/dist/types/forms/types.d.ts +9 -1
  135. package/dist/types/index.d.ts +7 -12
  136. package/dist/types/langchain/external-tool-wrapper.d.ts +101 -0
  137. package/dist/{cjs/langchain/FormAwareAgentExecutor.d.ts → types/langchain/form-aware-agent-executor.d.ts} +19 -12
  138. package/dist/types/langchain/index.d.ts +2 -0
  139. package/dist/{cjs → types/langchain}/langchain-agent.d.ts +15 -7
  140. package/dist/types/mcp/adapters/index.d.ts +1 -0
  141. package/dist/types/mcp/adapters/langchain.d.ts +1 -1
  142. package/dist/{cjs/mcp/ContentProcessor.d.ts → types/mcp/content-processor.d.ts} +1 -1
  143. package/dist/types/mcp/index.d.ts +5 -0
  144. package/dist/{cjs/mcp/MCPClientManager.d.ts → types/mcp/mcp-client-manager.d.ts} +1 -1
  145. package/dist/types/memory/{ContentStorage.d.ts → content-storage.d.ts} +4 -4
  146. package/dist/types/memory/index.d.ts +5 -7
  147. package/dist/{cjs/memory/MemoryWindow.d.ts → types/memory/memory-window.d.ts} +1 -1
  148. package/dist/{cjs/memory/SmartMemoryManager.d.ts → types/memory/smart-memory-manager.d.ts} +1 -1
  149. package/dist/types/services/{ContentStoreManager.d.ts → content-store-manager.d.ts} +6 -6
  150. package/dist/types/services/context/resolution-context.d.ts +49 -0
  151. package/dist/types/services/entity-resolver.d.ts +58 -0
  152. package/dist/types/services/formatters/converters/index.d.ts +2 -0
  153. package/dist/types/services/formatters/converters/string-normalization-converter.d.ts +13 -0
  154. package/dist/types/services/formatters/converters/topic-id-to-hrl-converter.d.ts +17 -0
  155. package/dist/types/services/formatters/format-converter-registry.d.ts +66 -0
  156. package/dist/types/services/formatters/index.d.ts +3 -0
  157. package/dist/types/services/formatters/types.d.ts +29 -0
  158. package/dist/types/services/index.d.ts +3 -0
  159. package/dist/types/services/resolution/resolution-pipeline.d.ts +44 -0
  160. package/dist/types/tools/index.d.ts +1 -0
  161. package/dist/types/utils/index.d.ts +1 -0
  162. package/package.json +30 -27
  163. package/src/agent-factory.ts +1 -1
  164. package/src/base-agent.ts +9 -0
  165. package/src/config/system-message.ts +2 -15
  166. package/src/constants/entity-references.ts +23 -0
  167. package/src/constants/form-priorities.ts +25 -0
  168. package/src/constants/index.ts +4 -0
  169. package/src/constants/messages.ts +20 -0
  170. package/src/constants/test-constants.ts +49 -0
  171. package/src/conversational-agent.ts +42 -69
  172. package/src/core/{ToolRegistry.ts → tool-registry.ts} +70 -44
  173. package/src/examples/external-tool-wrapper-example.ts +56 -0
  174. package/src/execution/{ExecutionPipeline.ts → execution-pipeline.ts} +3 -3
  175. package/src/forms/field-guidance-registry.ts +415 -0
  176. package/src/forms/field-type-registry.ts +49 -48
  177. package/src/forms/{FormEngine.ts → form-engine.ts} +66 -43
  178. package/src/forms/form-generator.ts +91 -17
  179. package/src/forms/index.ts +4 -1
  180. package/src/forms/types.ts +9 -1
  181. package/src/index.ts +7 -37
  182. package/src/langchain/external-tool-wrapper.ts +90 -0
  183. package/src/langchain/{FormAwareAgentExecutor.ts → form-aware-agent-executor.ts} +579 -351
  184. package/src/langchain/index.ts +2 -0
  185. package/src/{langchain-agent.ts → langchain/langchain-agent.ts} +389 -113
  186. package/src/mcp/adapters/index.ts +1 -0
  187. package/src/mcp/adapters/langchain.ts +27 -18
  188. package/src/mcp/{ContentProcessor.ts → content-processor.ts} +71 -47
  189. package/src/mcp/index.ts +5 -0
  190. package/src/mcp/{MCPClientManager.ts → mcp-client-manager.ts} +2 -2
  191. package/src/memory/{ContentStorage.ts → content-storage.ts} +263 -167
  192. package/src/memory/index.ts +5 -8
  193. package/src/memory/{MemoryWindow.ts → memory-window.ts} +47 -24
  194. package/src/memory/{SmartMemoryManager.ts → smart-memory-manager.ts} +49 -22
  195. package/src/plugins/hbar/HbarPlugin.ts +1 -1
  196. package/src/plugins/hcs-10/HCS10Plugin.ts +46 -28
  197. package/src/scripts/test-external-tool-wrapper.ts +6 -6
  198. package/src/scripts/test-inscribe-form-generation.ts +22 -21
  199. package/src/scripts/test-inscribe-wrapper-verification.ts +5 -4
  200. package/src/services/{ContentStoreManager.ts → content-store-manager.ts} +75 -33
  201. package/src/services/context/resolution-context.ts +80 -0
  202. package/src/services/entity-resolver.ts +425 -0
  203. package/src/services/formatters/converters/index.ts +2 -0
  204. package/src/services/formatters/converters/string-normalization-converter.ts +106 -0
  205. package/src/services/formatters/converters/topic-id-to-hrl-converter.ts +25 -0
  206. package/src/services/formatters/format-converter-registry.ts +229 -0
  207. package/src/services/formatters/index.ts +3 -0
  208. package/src/services/formatters/types.ts +31 -0
  209. package/src/services/index.ts +3 -0
  210. package/src/services/resolution/resolution-pipeline.ts +106 -0
  211. package/src/tools/index.ts +1 -0
  212. package/src/types/content-reference.ts +87 -60
  213. package/src/utils/index.ts +1 -0
  214. package/cli/dist/CLIApp.d.ts +0 -9
  215. package/cli/dist/CLIApp.js +0 -127
  216. package/cli/dist/LocalConversationalAgent.d.ts +0 -37
  217. package/cli/dist/LocalConversationalAgent.js +0 -58
  218. package/cli/dist/app.d.ts +0 -16
  219. package/cli/dist/app.js +0 -13
  220. package/cli/dist/cli.d.ts +0 -2
  221. package/cli/dist/cli.js +0 -51
  222. package/cli/dist/components/AppContainer.d.ts +0 -16
  223. package/cli/dist/components/AppContainer.js +0 -24
  224. package/cli/dist/components/AppScreens.d.ts +0 -2
  225. package/cli/dist/components/AppScreens.js +0 -259
  226. package/cli/dist/components/ChatScreen.d.ts +0 -15
  227. package/cli/dist/components/ChatScreen.js +0 -39
  228. package/cli/dist/components/DebugLoadingScreen.d.ts +0 -5
  229. package/cli/dist/components/DebugLoadingScreen.js +0 -31
  230. package/cli/dist/components/LoadingScreen.d.ts +0 -2
  231. package/cli/dist/components/LoadingScreen.js +0 -16
  232. package/cli/dist/components/LoadingScreenDebug.d.ts +0 -5
  233. package/cli/dist/components/LoadingScreenDebug.js +0 -27
  234. package/cli/dist/components/MCPConfigScreen.d.ts +0 -28
  235. package/cli/dist/components/MCPConfigScreen.js +0 -168
  236. package/cli/dist/components/ScreenRouter.d.ts +0 -12
  237. package/cli/dist/components/ScreenRouter.js +0 -22
  238. package/cli/dist/components/SetupScreen.d.ts +0 -15
  239. package/cli/dist/components/SetupScreen.js +0 -65
  240. package/cli/dist/components/SingleLoadingScreen.d.ts +0 -5
  241. package/cli/dist/components/SingleLoadingScreen.js +0 -27
  242. package/cli/dist/components/StatusBadge.d.ts +0 -7
  243. package/cli/dist/components/StatusBadge.js +0 -28
  244. package/cli/dist/components/TerminalWindow.d.ts +0 -8
  245. package/cli/dist/components/TerminalWindow.js +0 -24
  246. package/cli/dist/components/WelcomeScreen.d.ts +0 -11
  247. package/cli/dist/components/WelcomeScreen.js +0 -47
  248. package/cli/dist/context/AppContext.d.ts +0 -68
  249. package/cli/dist/context/AppContext.js +0 -363
  250. package/cli/dist/hooks/useInitializeAgent.d.ts +0 -19
  251. package/cli/dist/hooks/useInitializeAgent.js +0 -28
  252. package/cli/dist/hooks/useStableState.d.ts +0 -38
  253. package/cli/dist/hooks/useStableState.js +0 -68
  254. package/cli/dist/managers/AgentManager.d.ts +0 -57
  255. package/cli/dist/managers/AgentManager.js +0 -119
  256. package/cli/dist/managers/ConfigManager.d.ts +0 -53
  257. package/cli/dist/managers/ConfigManager.js +0 -173
  258. package/cli/dist/types.d.ts +0 -31
  259. package/cli/dist/types.js +0 -19
  260. package/dist/cjs/context/ReferenceContextManager.d.ts +0 -84
  261. package/dist/cjs/context/ReferenceResponseProcessor.d.ts +0 -76
  262. package/dist/cjs/langchain/FormValidatingToolWrapper.d.ts +0 -81
  263. package/dist/cjs/services/EntityResolver.d.ts +0 -26
  264. package/dist/types/context/ReferenceContextManager.d.ts +0 -84
  265. package/dist/types/context/ReferenceResponseProcessor.d.ts +0 -76
  266. package/dist/types/langchain/FormValidatingToolWrapper.d.ts +0 -81
  267. package/dist/types/services/EntityResolver.d.ts +0 -26
  268. package/src/context/ReferenceContextManager.ts +0 -350
  269. package/src/context/ReferenceResponseProcessor.ts +0 -295
  270. package/src/langchain/FormValidatingToolWrapper.ts +0 -355
  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/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
  275. /package/dist/cjs/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
  276. /package/dist/cjs/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
  277. /package/dist/cjs/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
  278. /package/dist/types/forms/{FormEngine.d.ts → form-engine.d.ts} +0 -0
  279. /package/dist/types/memory/{ReferenceIdGenerator.d.ts → reference-id-generator.d.ts} +0 -0
  280. /package/dist/types/memory/{TokenCounter.d.ts → token-counter.d.ts} +0 -0
  281. /package/dist/types/tools/{EntityResolverTool.d.ts → entity-resolver-tool.d.ts} +0 -0
  282. /package/dist/types/utils/{ResponseFormatter.d.ts → response-formatter.d.ts} +0 -0
  283. /package/src/memory/{ReferenceIdGenerator.ts → reference-id-generator.ts} +0 -0
  284. /package/src/memory/{TokenCounter.ts → token-counter.ts} +0 -0
  285. /package/src/tools/{EntityResolverTool.ts → entity-resolver-tool.ts} +0 -0
  286. /package/src/utils/{ResponseFormatter.ts → response-formatter.ts} +0 -0
@@ -1,308 +1,895 @@
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 "./index32.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;
64
92
  }
65
93
  }
66
- const validation = this.validateInput(tool, input);
67
- return !validation.isValid;
68
- }
69
- /**
70
- * Generate form from error context
71
- */
72
- async generateFormFromError(error, toolName, toolSchema, originalPrompt) {
73
- return this.formGenerator.generateFormFromError(
74
- error,
75
- toolSchema,
76
- toolName,
77
- originalPrompt
78
- );
79
- }
80
- /**
81
- * Generate form for FormValidatable tools
82
- */
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);
87
- }
88
- /**
89
- * Generate form based on schema validation
90
- */
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
101
- );
102
- if (this.isZodObject(schema)) {
94
+ if (shouldGenerateForm) {
95
+ this.formLogger.info(`🚨 FORM GENERATION TRIGGERED for ${toolName}`);
103
96
  try {
104
- const { jsonSchema, uiSchema } = this.formGenerator.generateJsonSchemaForm(
105
- schema,
106
- input,
107
- context.missingFields || /* @__PURE__ */ new Set()
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
+ }
108
155
  );
109
- formMessage.jsonSchema = jsonSchema;
110
- formMessage.uiSchema = uiSchema;
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
+ ];
111
238
  } catch (error) {
112
- this.logger.warn("Failed to generate JSON Schema for schema-based tool:", error);
239
+ this.formLogger.error(`Form generation failed for ${toolName}:`, error);
113
240
  }
114
241
  }
115
- formMessage.partialInput = input;
116
- return formMessage;
117
- }
118
- /**
119
- * Generate form based on render config
120
- */
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
242
+ this.formLogger.info(
243
+ `⚪ Passing through to normal tool execution for ${toolName}`
132
244
  );
133
- if (renderConfig) {
134
- formMessage.formConfig.metadata = {
135
- ...formMessage.formConfig.metadata,
136
- renderConfig
137
- };
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
+ }
138
335
  }
139
- formMessage.partialInput = input;
140
- return formMessage;
336
+ return super._takeNextStep(
337
+ nameToolMap,
338
+ inputs,
339
+ intermediateSteps,
340
+ runManager,
341
+ config
342
+ );
141
343
  }
142
344
  /**
143
- * Generate form from Zod validation error
345
+ * Helper to determine if a field is required in the schema
144
346
  */
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
- );
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;
152
392
  }
153
393
  /**
154
- * Validate input against tool schema
394
+ * Override _call to intercept Zod validation errors at the execution level
155
395
  */
156
- validateInput(tool, input) {
396
+ async _call(inputs) {
157
397
  try {
158
- const zodSchema = tool.schema;
159
- zodSchema.parse(input);
160
- return { isValid: true };
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;
161
451
  } catch (error) {
162
452
  if (error instanceof ZodError) {
163
- const errors = error.errors.map(
164
- (err) => `${err.path.join(".")}: ${err.message}`
165
- );
166
- return { isValid: false, errors };
453
+ this.formLogger.info("Intercepted ZodError during agent execution");
454
+ throw error;
167
455
  }
168
- return { isValid: false, errors: ["Validation failed"] };
456
+ throw error;
169
457
  }
170
458
  }
171
459
  /**
172
- * Check if schema is ZodObject
460
+ * Get a copy of pending forms for preservation during executor recreation
173
461
  */
174
- isZodObject(schema) {
175
- if (!schema || typeof schema !== "object") {
176
- return false;
177
- }
178
- const candidate = schema;
179
- return Boolean(candidate._def && candidate._def.typeName === "ZodObject");
462
+ getPendingForms() {
463
+ return new Map(this.pendingForms);
180
464
  }
181
465
  /**
182
- * Check if tool has render configuration
466
+ * Restore pending forms from a previous executor instance
183
467
  */
184
- hasRenderConfig(tool) {
185
- const schema = tool.schema;
186
- return !!(schema && schema._renderConfig);
468
+ restorePendingForms(forms) {
469
+ for (const [formId, formData] of forms) {
470
+ this.pendingForms.set(formId, formData);
471
+ }
187
472
  }
188
473
  /**
189
- * Extract render configuration from tool
474
+ * Processes form submission and continues tool execution
190
475
  */
191
- extractRenderConfig(tool) {
192
- const schema = tool.schema;
193
- return schema?._renderConfig;
476
+ async processFormSubmission(submission) {
477
+ this.formLogger.info(
478
+ "🚀 FormAwareAgentExecutor.processFormSubmission called!",
479
+ {
480
+ submissionFormId: submission.formId,
481
+ submissionToolName: submission.toolName
482
+ }
483
+ );
484
+ if (!submission) {
485
+ throw new Error("Form submission is null or undefined");
486
+ }
487
+ if (!submission.formId) {
488
+ throw new Error("Form submission missing formId");
489
+ }
490
+ if (!submission.parameters || submission.parameters === null || typeof submission.parameters !== "object" || Array.isArray(submission.parameters)) {
491
+ throw new Error(
492
+ `Form submission parameters are invalid: ${typeof submission.parameters}, isNull: ${submission.parameters === null}, isArray: ${Array.isArray(
493
+ submission.parameters
494
+ )}, parameters: ${JSON.stringify(submission.parameters)}`
495
+ );
496
+ }
497
+ this.formLogger.info("Processing form submission:", {
498
+ formId: submission.formId,
499
+ toolName: submission.toolName,
500
+ parameterKeys: Object.keys(submission.parameters),
501
+ parametersType: typeof submission.parameters,
502
+ parametersIsNull: submission.parameters === null,
503
+ parametersIsUndefined: submission.parameters === void 0,
504
+ hasContext: !!submission.context
505
+ });
506
+ let pendingForm = this.pendingForms.get(submission.formId);
507
+ if (!pendingForm) {
508
+ pendingForm = globalPendingForms.get(submission.formId);
509
+ if (!pendingForm) {
510
+ throw new Error(`No pending form found for ID: ${submission.formId}`);
511
+ }
512
+ }
513
+ this.pendingForms.delete(submission.formId);
514
+ globalPendingForms.delete(submission.formId);
515
+ const tool = pendingForm.toolRef || this.tools.find((t) => t.name === pendingForm.toolName);
516
+ if (!tool) {
517
+ throw new Error(
518
+ `Tool not found for form submission: ${pendingForm.toolName}`
519
+ );
520
+ }
521
+ let baseToolInput = {};
522
+ try {
523
+ if (pendingForm.originalToolInput && typeof pendingForm.originalToolInput === "object") {
524
+ baseToolInput = {
525
+ ...pendingForm.originalToolInput
526
+ };
527
+ }
528
+ } catch (error) {
529
+ this.formLogger.warn(
530
+ "Failed to extract base tool input, using empty object:",
531
+ error
532
+ );
533
+ baseToolInput = {};
534
+ }
535
+ let submissionData = {};
536
+ try {
537
+ if (submission.parameters && typeof submission.parameters === "object") {
538
+ submissionData = {
539
+ ...submission.parameters
540
+ };
541
+ }
542
+ } catch (error) {
543
+ this.formLogger.warn(
544
+ "Failed to extract submission parameters, using empty object:",
545
+ error
546
+ );
547
+ submissionData = {};
548
+ }
549
+ const mergedToolInput = {};
550
+ try {
551
+ Object.keys(baseToolInput).forEach((key) => {
552
+ const value = baseToolInput[key];
553
+ if (value !== void 0 && value !== null) {
554
+ mergedToolInput[key] = value;
555
+ }
556
+ });
557
+ Object.keys(submissionData).forEach((key) => {
558
+ const value = submissionData[key];
559
+ if (value !== void 0 && value !== null) {
560
+ mergedToolInput[key] = value;
561
+ }
562
+ });
563
+ mergedToolInput.renderForm = false;
564
+ mergedToolInput.__fromForm = true;
565
+ this.formLogger.info("Successfully merged tool input:", {
566
+ baseKeys: Object.keys(baseToolInput),
567
+ submissionKeys: Object.keys(submissionData),
568
+ mergedKeys: Object.keys(mergedToolInput)
569
+ });
570
+ } catch (error) {
571
+ this.formLogger.error("Failed to merge tool input data:", error);
572
+ throw new Error(
573
+ `Failed to merge tool input data: ${error instanceof Error ? error.message : "Unknown error"}`
574
+ );
575
+ }
576
+ try {
577
+ const maybeWrapper = tool;
578
+ let toolOutput;
579
+ if (typeof maybeWrapper.executeOriginal === "function") {
580
+ toolOutput = await maybeWrapper.executeOriginal(mergedToolInput);
581
+ } else if (typeof maybeWrapper.getOriginalTool === "function") {
582
+ const ot = maybeWrapper.getOriginalTool();
583
+ const otCall = ot;
584
+ if (ot && typeof otCall._call === "function") {
585
+ toolOutput = await otCall._call(mergedToolInput);
586
+ } else if (ot && typeof otCall.call === "function") {
587
+ toolOutput = await otCall.call(mergedToolInput);
588
+ } else {
589
+ const tcall = tool;
590
+ if (typeof tcall.call === "function") {
591
+ toolOutput = await tcall.call(mergedToolInput);
592
+ } else {
593
+ throw new Error(
594
+ "No callable tool implementation found for form submission"
595
+ );
596
+ }
597
+ }
598
+ } else if (maybeWrapper.originalTool && typeof maybeWrapper.originalTool._call === "function") {
599
+ toolOutput = await maybeWrapper.originalTool._call(mergedToolInput);
600
+ } else if (maybeWrapper.originalTool && typeof maybeWrapper.originalTool.call === "function") {
601
+ toolOutput = await maybeWrapper.originalTool.call(mergedToolInput);
602
+ } else if (typeof tool.call === "function") {
603
+ toolOutput = await tool.call(mergedToolInput);
604
+ } else {
605
+ throw new Error(
606
+ "No callable tool implementation found for form submission"
607
+ );
608
+ }
609
+ let responseMetadata = {};
610
+ let formattedOutput;
611
+ this.formLogger.info("🔍 METADATA EXTRACTION: Analyzing tool output", {
612
+ outputType: typeof toolOutput,
613
+ outputLength: toolOutput?.length || 0,
614
+ isString: typeof toolOutput === "string",
615
+ firstChars: typeof toolOutput === "string" ? toolOutput.substring(0, 100) : "not-string"
616
+ });
617
+ try {
618
+ const parsed = JSON.parse(toolOutput);
619
+ this.formLogger.info(
620
+ "✅ METADATA EXTRACTION: Successfully parsed JSON",
621
+ {
622
+ jsonKeys: Object.keys(parsed),
623
+ hasHashLinkBlock: !!parsed.hashLinkBlock
624
+ }
625
+ );
626
+ if (parsed && typeof parsed === "object") {
627
+ if (ResponseFormatter.isHashLinkResponse(parsed)) {
628
+ this.formLogger.info(
629
+ "🔗 HASHLINK DETECTED: Processing HashLink response separately to preserve metadata"
630
+ );
631
+ responseMetadata = {
632
+ ...responseMetadata,
633
+ hashLinkBlock: parsed.hashLinkBlock
634
+ };
635
+ formattedOutput = ResponseFormatter.formatHashLinkResponse(parsed);
636
+ this.formLogger.info(
637
+ "🔗 METADATA PRESERVED: HashLink metadata extracted for component rendering",
638
+ {
639
+ blockId: this.hasHashLinkBlock(responseMetadata) ? responseMetadata.hashLinkBlock.blockId : void 0,
640
+ hasTemplate: this.hasHashLinkBlock(responseMetadata) ? !!responseMetadata.hashLinkBlock.template : false
641
+ }
642
+ );
643
+ } else {
644
+ formattedOutput = ResponseFormatter.formatResponse(toolOutput);
645
+ responseMetadata = {
646
+ ...responseMetadata,
647
+ hashLinkBlock: parsed.hashLinkBlock
648
+ };
649
+ }
650
+ } else {
651
+ formattedOutput = ResponseFormatter.formatResponse(toolOutput);
652
+ }
653
+ } catch (error) {
654
+ this.formLogger.warn(
655
+ "❌ METADATA EXTRACTION: Tool output is not JSON",
656
+ {
657
+ error: error instanceof Error ? error.message : "unknown error",
658
+ outputSample: typeof toolOutput === "string" ? toolOutput.substring(0, 200) : "not-string"
659
+ }
660
+ );
661
+ formattedOutput = ResponseFormatter.formatResponse(toolOutput);
662
+ }
663
+ return {
664
+ output: formattedOutput,
665
+ formCompleted: true,
666
+ originalFormId: submission.formId,
667
+ intermediateSteps: [],
668
+ metadata: responseMetadata,
669
+ rawToolOutput: toolOutput,
670
+ toolName: pendingForm.toolName
671
+ };
672
+ } catch (error) {
673
+ if (error instanceof ZodError) {
674
+ throw error;
675
+ }
676
+ throw error;
677
+ }
194
678
  }
195
679
  /**
196
- * Resolve form schema for FormValidatable tools
680
+ * Extracts tool information from the execution context
197
681
  */
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 };
682
+ extractToolInfoFromError(error, inputs, intermediateSteps) {
683
+ try {
684
+ if (intermediateSteps.length > 0) {
685
+ const lastStep = intermediateSteps[intermediateSteps.length - 1];
686
+ if (lastStep.action && lastStep.action.tool) {
687
+ const tool = this.tools.find((t) => t.name === lastStep.action.tool);
688
+ if (tool && "schema" in tool) {
689
+ this.formLogger.info(
690
+ "Found tool from intermediate steps:",
691
+ lastStep.action.tool
692
+ );
693
+ return {
694
+ toolName: lastStep.action.tool,
695
+ schema: tool.schema
696
+ };
697
+ }
698
+ }
699
+ }
700
+ const inputSteps = inputs.intermediateSteps || [];
701
+ if (inputSteps.length > 0) {
702
+ const lastStep = inputSteps[inputSteps.length - 1];
703
+ let action;
704
+ if (Array.isArray(lastStep) && lastStep.length > 0) {
705
+ action = lastStep[0];
706
+ } else if (lastStep.action) {
707
+ action = lastStep.action;
708
+ } else {
709
+ action = lastStep;
710
+ }
711
+ if (action && action.tool) {
712
+ const tool = this.tools.find((t) => t.name === action.tool);
713
+ if (tool && "schema" in tool) {
714
+ this.formLogger.info("Found tool from input steps:", action.tool);
715
+ return {
716
+ toolName: action.tool,
717
+ schema: tool.schema
718
+ };
719
+ }
720
+ }
204
721
  }
722
+ const toolFromContext = this.findToolFromContext(inputs);
723
+ if (toolFromContext) {
724
+ this.formLogger.info(
725
+ "Found tool from context:",
726
+ toolFromContext.toolName
727
+ );
728
+ return toolFromContext;
729
+ }
730
+ return null;
731
+ } catch (err) {
732
+ this.formLogger.error("Error extracting tool info:", err);
733
+ return null;
205
734
  }
206
- return { schemaToUse: tool.schema, isFocusedSchema: false };
207
735
  }
208
736
  /**
209
- * Determine missing fields for form generation
737
+ * Attempts to find tool from execution context
210
738
  */
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);
739
+ findToolFromContext(inputs) {
740
+ const inputText = inputs.input || "";
741
+ for (const tool of this.tools) {
742
+ const keywords = this.extractToolKeywords(tool.name);
743
+ if (keywords.some(
744
+ (keyword) => inputText.toLowerCase().includes(keyword.toLowerCase())
745
+ )) {
746
+ if ("schema" in tool) {
747
+ return {
748
+ toolName: tool.name,
749
+ schema: tool.schema
750
+ };
223
751
  }
224
752
  }
225
753
  }
226
- return missingFields;
754
+ return null;
227
755
  }
228
756
  /**
229
- * Generate form with resolved schema
757
+ * Checks if a schema structure matches error paths
230
758
  */
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);
759
+ schemaMatchesErrorPaths(schema, errorPaths) {
760
+ const schemaRecord = schema;
761
+ if (!schemaRecord || !schemaRecord._def) return false;
762
+ try {
763
+ const def = schemaRecord._def;
764
+ if (def.typeName === "ZodObject") {
765
+ const shape = def.shape;
766
+ const schemaKeys = Object.keys(shape || {});
767
+ return errorPaths.some((path) => {
768
+ const topLevelKey = path.split(".")[0];
769
+ return schemaKeys.includes(topLevelKey);
770
+ });
252
771
  }
772
+ } catch (err) {
773
+ this.formLogger.debug("Error analyzing schema structure:", err);
253
774
  }
254
- formMessage.partialInput = input;
255
- return formMessage;
775
+ return false;
256
776
  }
257
777
  /**
258
- * Validate form submission
778
+ * Extracts keywords from tool name for matching
259
779
  */
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
- }
780
+ extractToolKeywords(toolName) {
781
+ const words = toolName.replace(/([A-Z])/g, " $1").toLowerCase().split(/[\s_-]+/).filter((w) => w.length > 2);
782
+ return [...words, toolName.toLowerCase()];
267
783
  }
268
784
  /**
269
- * Extract base tool input from context
785
+ * Formats the form message for display
270
786
  */
271
- extractBaseToolInput(context) {
272
- return context?.originalInput || {};
787
+ formatFormResponse(formMessage) {
788
+ const fieldCount = formMessage.formConfig.fields.length;
789
+ const fieldList = formMessage.formConfig.fields.slice(0, 3).map((f) => `• ${f.label}`).join("\n");
790
+ return `I need some additional information to complete your request.
791
+
792
+ ${formMessage.formConfig.description}
793
+
794
+ Required fields:
795
+ ${fieldList}${fieldCount > 3 ? `
796
+ ... and ${fieldCount - 3} more` : ""}
797
+
798
+ Please fill out the form below to continue.`;
273
799
  }
274
800
  /**
275
- * Extract submission data
801
+ * Check if there are pending forms
276
802
  */
277
- extractSubmissionData(submission) {
278
- return {
279
- ...submission.parameters,
280
- __fromForm: true
281
- };
803
+ hasPendingForms() {
804
+ return this.pendingForms.size > 0;
282
805
  }
283
806
  /**
284
- * Merge input data
807
+ * Get information about pending forms
285
808
  */
286
- mergeInputData(baseInput, submissionData) {
287
- return {
288
- ...baseInput,
289
- ...submissionData
290
- };
809
+ getPendingFormsInfo() {
810
+ return Array.from(this.pendingForms.entries()).map(([formId, info]) => ({
811
+ formId,
812
+ toolName: info.toolName
813
+ }));
291
814
  }
292
815
  /**
293
- * Get registered strategies
816
+ * Processes HashLink block responses from tools
294
817
  */
295
- getRegisteredStrategies() {
296
- return ["FormValidatable", "SchemaBased", "RenderConfig", "ZodErrorBased"];
818
+ processHashLinkResponse(toolResponse) {
819
+ try {
820
+ let hashLinkBlock;
821
+ if (toolResponse.hashLinkBlock) {
822
+ hashLinkBlock = toolResponse.hashLinkBlock;
823
+ } else if (toolResponse.success && toolResponse.inscription && toolResponse.hashLinkBlock) {
824
+ hashLinkBlock = toolResponse.hashLinkBlock;
825
+ }
826
+ if (!hashLinkBlock) {
827
+ throw new Error("HashLink block data not found in response");
828
+ }
829
+ if (!hashLinkBlock.blockId || !hashLinkBlock.hashLink || !hashLinkBlock.attributes) {
830
+ throw new Error(
831
+ "Invalid HashLink block structure - missing required fields"
832
+ );
833
+ }
834
+ let message = "Content processed successfully!";
835
+ if (toolResponse.success && toolResponse.inscription) {
836
+ const inscription = toolResponse.inscription;
837
+ const metadata = toolResponse.metadata || {};
838
+ message = `✅ ${inscription.standard} Hashinal inscription completed!
839
+
840
+ `;
841
+ if (metadata.name) {
842
+ message += `**${metadata.name}**
843
+ `;
844
+ }
845
+ if (metadata.description) {
846
+ message += `${metadata.description}
847
+
848
+ `;
849
+ }
850
+ message += `📍 **Topic ID:** ${inscription.topicId}
851
+ `;
852
+ message += `🔗 **HRL:** ${inscription.hrl}
853
+ `;
854
+ if (inscription.cdnUrl) {
855
+ message += `🌐 **CDN URL:** ${inscription.cdnUrl}
856
+ `;
857
+ }
858
+ if (metadata.creator) {
859
+ message += `👤 **Creator:** ${metadata.creator}
860
+ `;
861
+ }
862
+ }
863
+ this.formLogger.info("Processed HashLink response", {
864
+ blockId: hashLinkBlock.blockId,
865
+ hashLink: hashLinkBlock.hashLink,
866
+ hasTemplate: !!hashLinkBlock.template,
867
+ attributeCount: Object.keys(hashLinkBlock.attributes || {}).length
868
+ });
869
+ return {
870
+ hasHashLinkBlocks: true,
871
+ hashLinkBlock,
872
+ message
873
+ };
874
+ } catch (error) {
875
+ this.formLogger.error("Error processing HashLink response:", error);
876
+ return {
877
+ hasHashLinkBlocks: false,
878
+ message: "Content processed, but interactive display is not available."
879
+ };
880
+ }
297
881
  }
298
882
  /**
299
- * Get registered middleware
883
+ * Get FormEngine statistics for debugging
300
884
  */
301
- getRegisteredMiddleware() {
302
- return ["FormSubmissionValidator"];
885
+ getFormEngineStatistics() {
886
+ return {
887
+ strategies: this.formEngine.getRegisteredStrategies(),
888
+ middleware: this.formEngine.getRegisteredMiddleware()
889
+ };
303
890
  }
304
891
  }
305
892
  export {
306
- FormEngine
893
+ FormAwareAgentExecutor
307
894
  };
308
895
  //# sourceMappingURL=index29.js.map