@hashgraphonline/conversational-agent 0.1.214 → 0.1.217

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/cli/dist/CLIApp.d.ts +9 -0
  2. package/cli/dist/CLIApp.js +127 -0
  3. package/cli/dist/LocalConversationalAgent.d.ts +37 -0
  4. package/cli/dist/LocalConversationalAgent.js +58 -0
  5. package/cli/dist/app.d.ts +16 -0
  6. package/cli/dist/app.js +13 -0
  7. package/cli/dist/cli.d.ts +2 -0
  8. package/cli/dist/cli.js +51 -0
  9. package/cli/dist/components/AppContainer.d.ts +16 -0
  10. package/cli/dist/components/AppContainer.js +24 -0
  11. package/cli/dist/components/AppScreens.d.ts +2 -0
  12. package/cli/dist/components/AppScreens.js +259 -0
  13. package/cli/dist/components/ChatScreen.d.ts +15 -0
  14. package/cli/dist/components/ChatScreen.js +39 -0
  15. package/cli/dist/components/DebugLoadingScreen.d.ts +5 -0
  16. package/cli/dist/components/DebugLoadingScreen.js +31 -0
  17. package/cli/dist/components/LoadingScreen.d.ts +2 -0
  18. package/cli/dist/components/LoadingScreen.js +16 -0
  19. package/cli/dist/components/LoadingScreenDebug.d.ts +5 -0
  20. package/cli/dist/components/LoadingScreenDebug.js +27 -0
  21. package/cli/dist/components/MCPConfigScreen.d.ts +28 -0
  22. package/cli/dist/components/MCPConfigScreen.js +168 -0
  23. package/cli/dist/components/ScreenRouter.d.ts +12 -0
  24. package/cli/dist/components/ScreenRouter.js +22 -0
  25. package/cli/dist/components/SetupScreen.d.ts +15 -0
  26. package/cli/dist/components/SetupScreen.js +65 -0
  27. package/cli/dist/components/SingleLoadingScreen.d.ts +5 -0
  28. package/cli/dist/components/SingleLoadingScreen.js +27 -0
  29. package/cli/dist/components/StatusBadge.d.ts +7 -0
  30. package/cli/dist/components/StatusBadge.js +28 -0
  31. package/cli/dist/components/TerminalWindow.d.ts +8 -0
  32. package/cli/dist/components/TerminalWindow.js +24 -0
  33. package/cli/dist/components/WelcomeScreen.d.ts +11 -0
  34. package/cli/dist/components/WelcomeScreen.js +47 -0
  35. package/cli/dist/context/AppContext.d.ts +68 -0
  36. package/cli/dist/context/AppContext.js +363 -0
  37. package/cli/dist/hooks/useInitializeAgent.d.ts +19 -0
  38. package/cli/dist/hooks/useInitializeAgent.js +28 -0
  39. package/cli/dist/hooks/useStableState.d.ts +38 -0
  40. package/cli/dist/hooks/useStableState.js +68 -0
  41. package/cli/dist/managers/AgentManager.d.ts +57 -0
  42. package/cli/dist/managers/AgentManager.js +119 -0
  43. package/cli/dist/managers/ConfigManager.d.ts +53 -0
  44. package/cli/dist/managers/ConfigManager.js +173 -0
  45. package/cli/dist/types.d.ts +31 -0
  46. package/cli/dist/types.js +19 -0
  47. package/dist/cjs/base-agent.d.ts +2 -0
  48. package/dist/cjs/conversational-agent.d.ts +8 -0
  49. package/dist/cjs/core/ToolRegistry.d.ts +130 -0
  50. package/dist/cjs/execution/ExecutionPipeline.d.ts +81 -0
  51. package/dist/cjs/forms/FormEngine.d.ts +121 -0
  52. package/dist/cjs/forms/field-type-registry.d.ts +51 -0
  53. package/dist/cjs/forms/form-generator.d.ts +123 -0
  54. package/dist/cjs/forms/index.d.ts +2 -0
  55. package/dist/cjs/forms/types.d.ts +108 -0
  56. package/dist/cjs/index.cjs +1 -1
  57. package/dist/cjs/index.cjs.map +1 -1
  58. package/dist/cjs/index.d.ts +5 -0
  59. package/dist/cjs/langchain/FormAwareAgentExecutor.d.ts +108 -0
  60. package/dist/cjs/langchain/FormValidatingToolWrapper.d.ts +81 -0
  61. package/dist/cjs/langchain-agent.d.ts +65 -0
  62. package/dist/cjs/memory/ContentStorage.d.ts +7 -0
  63. package/dist/cjs/memory/SmartMemoryManager.d.ts +1 -0
  64. package/dist/cjs/services/ContentStoreManager.d.ts +11 -1
  65. package/dist/cjs/utils/ResponseFormatter.d.ts +26 -0
  66. package/dist/esm/index.js +8 -1
  67. package/dist/esm/index.js.map +1 -1
  68. package/dist/esm/index12.js +1 -1
  69. package/dist/esm/index12.js.map +1 -1
  70. package/dist/esm/index14.js +23 -5
  71. package/dist/esm/index14.js.map +1 -1
  72. package/dist/esm/index15.js +25 -4
  73. package/dist/esm/index15.js.map +1 -1
  74. package/dist/esm/index16.js +4 -2
  75. package/dist/esm/index16.js.map +1 -1
  76. package/dist/esm/index17.js +2 -7
  77. package/dist/esm/index17.js.map +1 -1
  78. package/dist/esm/index18.js +609 -36
  79. package/dist/esm/index18.js.map +1 -1
  80. package/dist/esm/index19.js +229 -84
  81. package/dist/esm/index19.js.map +1 -1
  82. package/dist/esm/index20.js +111 -17
  83. package/dist/esm/index20.js.map +1 -1
  84. package/dist/esm/index21.js +44 -7
  85. package/dist/esm/index21.js.map +1 -1
  86. package/dist/esm/index22.js +86 -157
  87. package/dist/esm/index22.js.map +1 -1
  88. package/dist/esm/index23.js +32 -150
  89. package/dist/esm/index23.js.map +1 -1
  90. package/dist/esm/index24.js +746 -80
  91. package/dist/esm/index24.js.map +1 -1
  92. package/dist/esm/index25.js +154 -45
  93. package/dist/esm/index25.js.map +1 -1
  94. package/dist/esm/index26.js +149 -24
  95. package/dist/esm/index26.js.map +1 -1
  96. package/dist/esm/index27.js +196 -217
  97. package/dist/esm/index27.js.map +1 -1
  98. package/dist/esm/index28.js +187 -0
  99. package/dist/esm/index28.js.map +1 -0
  100. package/dist/esm/index29.js +308 -0
  101. package/dist/esm/index29.js.map +1 -0
  102. package/dist/esm/index30.js +159 -0
  103. package/dist/esm/index30.js.map +1 -0
  104. package/dist/esm/index31.js +68 -0
  105. package/dist/esm/index31.js.map +1 -0
  106. package/dist/esm/index32.js +30 -0
  107. package/dist/esm/index32.js.map +1 -0
  108. package/dist/esm/index33.js +95 -0
  109. package/dist/esm/index33.js.map +1 -0
  110. package/dist/esm/index34.js +245 -0
  111. package/dist/esm/index34.js.map +1 -0
  112. package/dist/esm/index5.js +2 -2
  113. package/dist/esm/index5.js.map +1 -1
  114. package/dist/esm/index6.js +68 -25
  115. package/dist/esm/index6.js.map +1 -1
  116. package/dist/esm/index7.js.map +1 -1
  117. package/dist/esm/index8.js +744 -70
  118. package/dist/esm/index8.js.map +1 -1
  119. package/dist/types/base-agent.d.ts +2 -0
  120. package/dist/types/conversational-agent.d.ts +8 -0
  121. package/dist/types/core/ToolRegistry.d.ts +130 -0
  122. package/dist/types/execution/ExecutionPipeline.d.ts +81 -0
  123. package/dist/types/forms/FormEngine.d.ts +121 -0
  124. package/dist/types/forms/field-type-registry.d.ts +51 -0
  125. package/dist/types/forms/form-generator.d.ts +123 -0
  126. package/dist/types/forms/index.d.ts +2 -0
  127. package/dist/types/forms/types.d.ts +108 -0
  128. package/dist/types/index.d.ts +5 -0
  129. package/dist/types/langchain/FormAwareAgentExecutor.d.ts +108 -0
  130. package/dist/types/langchain/FormValidatingToolWrapper.d.ts +81 -0
  131. package/dist/types/langchain-agent.d.ts +65 -0
  132. package/dist/types/memory/ContentStorage.d.ts +7 -0
  133. package/dist/types/memory/SmartMemoryManager.d.ts +1 -0
  134. package/dist/types/services/ContentStoreManager.d.ts +11 -1
  135. package/dist/types/utils/ResponseFormatter.d.ts +26 -0
  136. package/package.json +35 -34
  137. package/src/base-agent.ts +2 -0
  138. package/src/config/system-message.ts +14 -0
  139. package/src/context/ReferenceContextManager.ts +1 -1
  140. package/src/conversational-agent.ts +95 -38
  141. package/src/core/ToolRegistry.ts +358 -0
  142. package/src/execution/ExecutionPipeline.ts +301 -0
  143. package/src/forms/FormEngine.ts +443 -0
  144. package/src/forms/field-type-registry.ts +203 -0
  145. package/src/forms/form-generator.ts +841 -0
  146. package/src/forms/index.ts +2 -0
  147. package/src/forms/types.ts +125 -0
  148. package/src/index.ts +9 -0
  149. package/src/langchain/FormAwareAgentExecutor.ts +971 -0
  150. package/src/langchain/FormValidatingToolWrapper.ts +355 -0
  151. package/src/langchain-agent.ts +1034 -87
  152. package/src/mcp/ContentProcessor.ts +20 -4
  153. package/src/mcp/MCPClientManager.ts +1 -1
  154. package/src/mcp/adapters/langchain.ts +1 -1
  155. package/src/memory/ContentStorage.ts +25 -5
  156. package/src/memory/SmartMemoryManager.ts +27 -4
  157. package/src/memory/TokenCounter.ts +1 -1
  158. package/src/plugins/hbar/HbarPlugin.ts +0 -1
  159. package/src/scripts/test-external-tool-wrapper.ts +103 -0
  160. package/src/scripts/test-hedera-kit-wrapper.ts +265 -0
  161. package/src/scripts/test-inscribe-form-generation.ts +494 -0
  162. package/src/scripts/test-inscribe-wrapper-verification.ts +220 -0
  163. package/src/services/ContentStoreManager.ts +23 -9
  164. package/src/services/EntityResolver.ts +2 -9
  165. package/src/tools/EntityResolverTool.ts +5 -8
  166. package/src/utils/ResponseFormatter.ts +146 -0
  167. package/cli/readme.md +0 -181
  168. package/dist/cjs/langchain/ContentAwareAgentExecutor.d.ts +0 -14
  169. package/dist/types/langchain/ContentAwareAgentExecutor.d.ts +0 -14
  170. package/src/langchain/ContentAwareAgentExecutor.ts +0 -19
@@ -1,49 +1,622 @@
1
- import { z } from "zod";
2
- import { AccountBuilder } from "./index24.js";
3
- import { BaseHederaTransactionTool } from "hedera-agent-kit";
4
- const HbarTransferInputSchema = z.object({
5
- accountId: z.string().describe('Account ID for the transfer (e.g., "0.0.xxxx").'),
6
- amount: z.union([z.number(), z.string()]).describe(
7
- "HBAR amount in decimal format (e.g., 1 for 1 HBAR, 0.5 for 0.5 HBAR). Positive for credit, negative for debit. DO NOT multiply by 10^8 for tinybars - just use the HBAR amount directly."
8
- )
9
- });
10
- const TransferHbarZodSchemaCore = z.object({
11
- transfers: z.array(HbarTransferInputSchema).min(1).describe(
12
- 'Array of transfers. For simple transfers from your operator account, just include the recipient with positive amount: [{accountId: "0.0.800", amount: 1}]. For complex multi-party transfers, include all parties with negative amounts for senders and positive for receivers.'
13
- ),
14
- memo: z.string().optional().describe("Optional. Memo for the transaction.")
15
- });
16
- class TransferHbarTool extends BaseHederaTransactionTool {
1
+ import { zodToJsonSchema } from "zod-to-json-schema";
2
+ import { extractRenderConfigs, generateFieldOrdering } from "@hashgraphonline/standards-agent-kit";
3
+ import { Logger } from "@hashgraphonline/standards-sdk";
4
+ import { fieldTypeRegistry } from "./index30.js";
5
+ class FormGenerator {
17
6
  constructor() {
18
- super(...arguments);
19
- this.name = "hedera-account-transfer-hbar-v2";
20
- this.description = 'PRIMARY TOOL FOR HBAR TRANSFERS: Transfers HBAR between accounts. For simple transfers from the operator account, just specify the recipient with a positive amount (e.g., [{accountId: "0.0.800", amount: 1}] to send 1 HBAR to 0.0.800). The sender will be automatically added. For multi-party transfers (e.g., "A sends 5 HBAR to C and B sends 3 HBAR to C"), include ALL transfers with their amounts (negative for senders, positive for receivers).';
21
- this.specificInputSchema = TransferHbarZodSchemaCore;
22
- this.namespace = "account";
7
+ this.logger = new Logger({ module: "FormGenerator" });
23
8
  }
24
9
  /**
25
- * Creates and returns the service builder for account operations.
26
- *
27
- * @returns BaseServiceBuilder instance configured for account operations
10
+ * Creates a form message from a Zod validation error
11
+ * @param error The Zod validation error
12
+ * @param schema The original Zod schema
13
+ * @param toolName Name of the tool that failed validation
14
+ * @param originalPrompt The user's original request
15
+ * @returns FormMessage to send to the chat UI
28
16
  */
29
- getServiceBuilder() {
30
- return new AccountBuilder(this.hederaKit);
17
+ generateFormFromError(error, schema, toolName, originalPrompt) {
18
+ const validationErrors = this.extractValidationErrors(error);
19
+ const missingFields = this.identifyMissingFields(validationErrors, schema);
20
+ const formConfig = this.createFormConfig(schema, missingFields, toolName);
21
+ return {
22
+ type: "form",
23
+ id: `form_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
24
+ formConfig,
25
+ originalPrompt,
26
+ toolName,
27
+ validationErrors
28
+ };
31
29
  }
32
30
  /**
33
- * Executes the HBAR transfer using the provided builder and arguments.
34
- * Validates that all transfers sum to zero before execution.
35
- *
36
- * @param builder - The service builder instance for executing transactions
37
- * @param specificArgs - The validated transfer parameters including transfers array and optional memo
38
- * @returns Promise that resolves when the transfer is complete
31
+ * Generates a form from a schema and partial input
32
+ * @param schema The Zod schema to generate a form from
33
+ * @param partialInput Any partial input already provided
34
+ * @param context Additional context about the tool
35
+ * @param preCalculatedMissingFields Optional pre-calculated missing fields set. If undefined, includes all fields from schema.
36
+ * @returns FormMessage to send to the chat UI
39
37
  */
40
- async callBuilderMethod(builder, specificArgs) {
41
- await builder.transferHbar(
42
- specificArgs
38
+ async generateFormFromSchema(schema, partialInput, context, preCalculatedMissingFields) {
39
+ let missingFields;
40
+ this.logger.info(`🏁 FormGenerator.generateFormFromSchema starting`, {
41
+ toolName: context.toolName,
42
+ partialInput,
43
+ hasSchema: !!schema,
44
+ hasShape: !!(schema && schema.shape),
45
+ hasPreCalculatedFields: preCalculatedMissingFields !== void 0,
46
+ preCalculatedFieldsSize: preCalculatedMissingFields?.size || 0
47
+ });
48
+ if (preCalculatedMissingFields !== void 0) {
49
+ missingFields = preCalculatedMissingFields;
50
+ this.logger.info(`📋 Using pre-calculated missing fields`, {
51
+ missingFieldsCount: missingFields.size,
52
+ missingFields: Array.from(missingFields)
53
+ });
54
+ } else {
55
+ missingFields = /* @__PURE__ */ new Set();
56
+ const zodObject = this.extractZodObject(schema);
57
+ if (zodObject) {
58
+ const shape = zodObject.shape;
59
+ for (const fieldName of Object.keys(shape)) {
60
+ missingFields.add(fieldName);
61
+ this.logger.info(
62
+ `⭐ Including all fields from focused schema: ${fieldName}`
63
+ );
64
+ }
65
+ }
66
+ this.logger.info(`📋 Using ALL fields from focused schema`, {
67
+ totalFields: zodObject ? Object.keys(zodObject.shape).length : 0,
68
+ missingFieldsCount: missingFields.size,
69
+ missingFields: Array.from(missingFields)
70
+ });
71
+ }
72
+ const formConfig = this.createFormConfig(
73
+ schema,
74
+ missingFields,
75
+ context.toolName,
76
+ preCalculatedMissingFields
43
77
  );
78
+ return {
79
+ type: "form",
80
+ id: `form_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
81
+ formConfig,
82
+ originalPrompt: context.toolDescription || `Complete ${context.toolName}`,
83
+ toolName: context.toolName,
84
+ validationErrors: []
85
+ };
86
+ }
87
+ /**
88
+ * Extracts validation errors from ZodError
89
+ */
90
+ extractValidationErrors(error) {
91
+ return error.issues.map((issue) => ({
92
+ path: issue.path.map((p) => String(p)),
93
+ message: issue.message,
94
+ code: issue.code
95
+ }));
96
+ }
97
+ /**
98
+ * Identifies which fields are missing or invalid from validation errors
99
+ */
100
+ identifyMissingFields(errors, _schema) {
101
+ const missingFields = /* @__PURE__ */ new Set();
102
+ errors.forEach((error) => {
103
+ const fieldPath = error.path.join(".");
104
+ if (fieldPath) {
105
+ missingFields.add(fieldPath);
106
+ }
107
+ });
108
+ return missingFields;
109
+ }
110
+ /**
111
+ * Creates form configuration from schema
112
+ */
113
+ createFormConfig(schema, missingFields, toolName, preCalculatedMissingFields) {
114
+ const extractedConfig = this.extractRenderConfigsSafely(schema);
115
+ const fieldOrdering = this.generateFieldOrderingSafely(schema);
116
+ const fields = this.generateFormFields(
117
+ schema,
118
+ extractedConfig,
119
+ missingFields,
120
+ fieldOrdering,
121
+ preCalculatedMissingFields
122
+ );
123
+ return {
124
+ title: this.generateFormTitle(toolName),
125
+ description: this.generateFormDescription(toolName, missingFields.size),
126
+ fields,
127
+ submitLabel: "Continue",
128
+ cancelLabel: "Cancel",
129
+ metadata: {
130
+ toolName,
131
+ missingFieldCount: missingFields.size
132
+ }
133
+ };
134
+ }
135
+ /**
136
+ * Safely extracts render configs from schema
137
+ */
138
+ extractRenderConfigsSafely(schema) {
139
+ try {
140
+ if (typeof extractRenderConfigs === "function") {
141
+ return extractRenderConfigs(schema);
142
+ }
143
+ } catch (error) {
144
+ this.logger.warn("Could not extract render configs:", error);
145
+ }
146
+ return {
147
+ fields: {},
148
+ groups: {},
149
+ order: [],
150
+ metadata: {}
151
+ };
152
+ }
153
+ /**
154
+ * Safely generates field ordering from schema
155
+ */
156
+ generateFieldOrderingSafely(schema) {
157
+ try {
158
+ if (typeof generateFieldOrdering === "function") {
159
+ const ordering = generateFieldOrdering(
160
+ schema
161
+ );
162
+ const sections = Object.values(ordering.sections).map((section) => ({
163
+ fields: section.fields
164
+ }));
165
+ return { sections };
166
+ }
167
+ } catch (error) {
168
+ this.logger.warn("Could not generate field ordering:", error);
169
+ }
170
+ return { sections: [] };
171
+ }
172
+ /**
173
+ * Determines field priority for progressive disclosure
174
+ */
175
+ getFieldPriority(name, renderConfig, isRequired) {
176
+ if (renderConfig?.ui?.priority) {
177
+ const priority = renderConfig.ui.priority;
178
+ if (["essential", "common", "advanced", "expert"].includes(priority)) {
179
+ return priority;
180
+ }
181
+ }
182
+ if (isRequired === true) {
183
+ return "essential";
184
+ }
185
+ const ui = renderConfig?.ui;
186
+ if (ui?.advanced === true) {
187
+ return "advanced";
188
+ }
189
+ if (ui?.expert === true) {
190
+ return "expert";
191
+ }
192
+ return "common";
193
+ }
194
+ /**
195
+ * Determines which fields should be included in the form
196
+ */
197
+ determineFieldsToInclude(schema, missingFields, preCalculatedMissingFields) {
198
+ const fieldsToInclude = /* @__PURE__ */ new Set();
199
+ if (preCalculatedMissingFields === void 0) {
200
+ this.logger.info(
201
+ `⭐ Focused schema mode - including ALL fields from schema`
202
+ );
203
+ const allSchemaFields = this.extractFieldsFromSchema(schema);
204
+ allSchemaFields.forEach((fieldName) => {
205
+ fieldsToInclude.add(fieldName);
206
+ this.logger.info(`✅ Including focused schema field: ${fieldName}`);
207
+ });
208
+ } else if (preCalculatedMissingFields.size > 0) {
209
+ this.logger.info(
210
+ `📋 Using ONLY pre-calculated missing fields (${preCalculatedMissingFields.size} fields)`,
211
+ { fields: Array.from(preCalculatedMissingFields) }
212
+ );
213
+ preCalculatedMissingFields.forEach((fieldName) => {
214
+ fieldsToInclude.add(fieldName);
215
+ this.logger.info(`✅ Including pre-calculated field: ${fieldName}`);
216
+ });
217
+ } else {
218
+ this.logger.info(
219
+ "⚠️ No pre-calculated fields, falling back to schema analysis"
220
+ );
221
+ this.includeRequiredMissingFields(schema, missingFields, fieldsToInclude);
222
+ }
223
+ return fieldsToInclude;
224
+ }
225
+ /**
226
+ * Includes required fields that are missing
227
+ */
228
+ includeRequiredMissingFields(schema, missingFields, fieldsToInclude) {
229
+ const allSchemaFields = this.extractFieldsFromSchema(schema);
230
+ allSchemaFields.forEach((fieldName) => {
231
+ const isRequired = this.isFieldRequired(schema, fieldName);
232
+ const isMissing = missingFields.has(fieldName);
233
+ const shouldInclude = isMissing && isRequired;
234
+ this.logger.info(`🔍 FormGenerator field inclusion check: ${fieldName}`, {
235
+ isRequired,
236
+ isMissing,
237
+ shouldInclude
238
+ });
239
+ if (shouldInclude) {
240
+ fieldsToInclude.add(fieldName);
241
+ }
242
+ });
243
+ }
244
+ /**
245
+ * Creates form fields from ordered field names
246
+ */
247
+ createOrderedFields(fieldsToInclude, fieldOrdering, extractedConfig, schema) {
248
+ const fields = [];
249
+ const processedFields = /* @__PURE__ */ new Set();
250
+ if (fieldOrdering.sections.length > 0) {
251
+ const orderedFieldNames = fieldOrdering.sections.flatMap((s) => s.fields);
252
+ orderedFieldNames.forEach((fieldName) => {
253
+ if (fieldsToInclude.has(fieldName) && !processedFields.has(fieldName)) {
254
+ const field = this.createFormField(
255
+ fieldName,
256
+ extractedConfig.fields[fieldName],
257
+ schema,
258
+ fieldName
259
+ );
260
+ if (field) {
261
+ fields.push(field);
262
+ processedFields.add(fieldName);
263
+ }
264
+ }
265
+ });
266
+ }
267
+ fieldsToInclude.forEach((fieldName) => {
268
+ if (!processedFields.has(fieldName)) {
269
+ const field = this.createFormField(
270
+ fieldName,
271
+ extractedConfig.fields[fieldName],
272
+ schema,
273
+ fieldName
274
+ );
275
+ if (field) {
276
+ fields.push(field);
277
+ }
278
+ }
279
+ });
280
+ return fields;
281
+ }
282
+ /**
283
+ * Generates form fields from schema and validation errors
284
+ */
285
+ generateFormFields(schema, extractedConfig, missingFields, fieldOrdering, preCalculatedMissingFields) {
286
+ const fieldsToInclude = this.determineFieldsToInclude(
287
+ schema,
288
+ missingFields,
289
+ preCalculatedMissingFields
290
+ );
291
+ let fields = this.createOrderedFields(
292
+ fieldsToInclude,
293
+ fieldOrdering,
294
+ extractedConfig,
295
+ schema
296
+ );
297
+ if (fields.length === 0 && missingFields.size > 0) {
298
+ fields = Array.from(missingFields).map(
299
+ (fieldName) => this.createFormField(
300
+ fieldName,
301
+ extractedConfig.fields[fieldName],
302
+ schema,
303
+ fieldName
304
+ )
305
+ ).filter(
306
+ (field) => field !== null && field !== void 0
307
+ );
308
+ }
309
+ return fields;
310
+ }
311
+ /**
312
+ * Creates a single form field
313
+ */
314
+ createFormField(fieldName, renderConfig, schema, fieldPath) {
315
+ const type = this.mapFieldType(renderConfig?.fieldType, schema, fieldPath);
316
+ const isRequired = this.isFieldRequired(schema, fieldPath || fieldName);
317
+ const field = {
318
+ name: fieldName,
319
+ label: renderConfig?.ui?.label || this.humanizeFieldName(fieldName),
320
+ type,
321
+ required: isRequired,
322
+ priority: this.getFieldPriority(fieldName, renderConfig, isRequired)
323
+ };
324
+ if (renderConfig) {
325
+ field.renderConfig = renderConfig;
326
+ }
327
+ if (renderConfig?.ui?.placeholder) {
328
+ field.placeholder = renderConfig.ui.placeholder;
329
+ }
330
+ if (renderConfig?.ui?.helpText) {
331
+ field.helpText = renderConfig.ui.helpText;
332
+ }
333
+ if (renderConfig?.constraints) {
334
+ const validation = {};
335
+ if (renderConfig.constraints.min !== void 0)
336
+ validation.min = renderConfig.constraints.min;
337
+ if (renderConfig.constraints.max !== void 0)
338
+ validation.max = renderConfig.constraints.max;
339
+ if (renderConfig.constraints.minLength !== void 0)
340
+ validation.minLength = renderConfig.constraints.minLength;
341
+ if (renderConfig.constraints.maxLength !== void 0)
342
+ validation.maxLength = renderConfig.constraints.maxLength;
343
+ if (renderConfig.constraints.pattern !== void 0)
344
+ validation.pattern = renderConfig.constraints.pattern;
345
+ if (Object.keys(validation).length > 0) {
346
+ field.validation = validation;
347
+ }
348
+ }
349
+ if (renderConfig?.options) {
350
+ field.options = renderConfig.options.map((opt) => ({
351
+ value: String(opt.value),
352
+ label: opt.label,
353
+ ...opt.disabled !== void 0 && { disabled: opt.disabled }
354
+ }));
355
+ }
356
+ return field;
357
+ }
358
+ /**
359
+ * Maps render config field type to form field type with fallback inference
360
+ */
361
+ mapFieldType(fieldType, schema, fieldPath) {
362
+ if (!fieldType && schema && fieldPath) {
363
+ const inferredType = this.inferTypeFromSchema(schema, fieldPath);
364
+ if (inferredType) {
365
+ return inferredType;
366
+ }
367
+ }
368
+ if (!fieldType && fieldPath) {
369
+ const registryType = fieldTypeRegistry.detectType(fieldPath);
370
+ if (registryType) {
371
+ return registryType;
372
+ }
373
+ }
374
+ if (!fieldType) {
375
+ return "text";
376
+ }
377
+ const normalizedType = fieldType.toLowerCase();
378
+ if (["text", "string"].includes(normalizedType)) return "text";
379
+ if (["number", "integer", "float", "decimal"].includes(normalizedType))
380
+ return "number";
381
+ if (["select", "enum", "dropdown"].includes(normalizedType))
382
+ return "select";
383
+ if (["checkbox", "boolean", "bool"].includes(normalizedType))
384
+ return "checkbox";
385
+ if (["textarea", "longtext", "multiline"].includes(normalizedType))
386
+ return "textarea";
387
+ if (["file", "upload", "attachment"].includes(normalizedType))
388
+ return "file";
389
+ if (["array", "list"].includes(normalizedType)) return "array";
390
+ if (["object", "json"].includes(normalizedType)) return "object";
391
+ if (["currency", "money", "price"].includes(normalizedType))
392
+ return "currency";
393
+ if (["percentage", "percent"].includes(normalizedType)) return "percentage";
394
+ return "text";
395
+ }
396
+ /**
397
+ * Converts field name to human-readable label
398
+ */
399
+ humanizeFieldName(fieldName) {
400
+ return fieldName.replace(/([A-Z])/g, " $1").replace(/_/g, " ").replace(/\./g, " ").trim().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
401
+ }
402
+ /**
403
+ * Generates a title for the form
404
+ */
405
+ generateFormTitle(toolName) {
406
+ const cleanName = toolName.replace(/Tool$/, "").replace(/Hedera/g, "").replace(/([A-Z])/g, " $1").trim();
407
+ return `Complete ${cleanName} Information`;
408
+ }
409
+ /**
410
+ * Safely extracts ZodObject from a schema, returns null if not an object schema
411
+ */
412
+ extractZodObject(schema) {
413
+ try {
414
+ const def = schema._def;
415
+ if (def && def.typeName === "ZodObject") {
416
+ return schema;
417
+ }
418
+ } catch (error) {
419
+ this.logger.debug("Could not extract ZodObject from schema:", error);
420
+ }
421
+ return null;
422
+ }
423
+ /**
424
+ * Extracts field names from Zod schema structure
425
+ */
426
+ extractFieldsFromSchema(schema) {
427
+ const fields = [];
428
+ const zodObject = this.extractZodObject(schema);
429
+ if (zodObject) {
430
+ fields.push(...Object.keys(zodObject.shape));
431
+ return fields;
432
+ }
433
+ try {
434
+ const def = schema._def;
435
+ if (def && def.typeName === "ZodUnion" && def.options) {
436
+ const firstOption = def.options[0];
437
+ const firstOptionObject = this.extractZodObject(firstOption);
438
+ if (firstOptionObject) {
439
+ fields.push(...Object.keys(firstOptionObject.shape));
440
+ }
441
+ }
442
+ } catch (error) {
443
+ this.logger.debug(
444
+ "Could not extract fields from schema structure:",
445
+ error
446
+ );
447
+ }
448
+ return fields;
449
+ }
450
+ /**
451
+ * Infers field type from Zod schema
452
+ */
453
+ inferTypeFromSchema(schema, fieldPath) {
454
+ try {
455
+ const zodObject = this.extractZodObject(schema);
456
+ if (!zodObject) return null;
457
+ const shape = zodObject.shape;
458
+ if (!shape) return null;
459
+ let fieldSchema = shape[fieldPath];
460
+ if (!fieldSchema) return null;
461
+ const fieldDef = fieldSchema._def;
462
+ if (fieldDef && fieldDef.typeName === "ZodOptional" && fieldDef.innerType) {
463
+ fieldSchema = fieldDef.innerType;
464
+ }
465
+ if (!fieldSchema || !fieldSchema._def) return null;
466
+ const typeDef = fieldSchema._def;
467
+ const fieldTypeName = typeDef.typeName;
468
+ const lowerPath = fieldPath.toLowerCase();
469
+ switch (fieldTypeName) {
470
+ case "ZodString":
471
+ if (lowerPath.includes("memo") || lowerPath.includes("description")) {
472
+ return "textarea";
473
+ }
474
+ return "text";
475
+ case "ZodNumber":
476
+ if (lowerPath.includes("percent")) {
477
+ return "percentage";
478
+ }
479
+ if (lowerPath.includes("price") || lowerPath.includes("cost")) {
480
+ return "currency";
481
+ }
482
+ return "number";
483
+ case "ZodBoolean":
484
+ return "checkbox";
485
+ case "ZodEnum":
486
+ case "ZodNativeEnum":
487
+ return "select";
488
+ case "ZodArray":
489
+ return "array";
490
+ case "ZodObject":
491
+ return "object";
492
+ default:
493
+ return "text";
494
+ }
495
+ } catch (error) {
496
+ this.logger.debug("Could not infer type from schema:", error);
497
+ }
498
+ return null;
499
+ }
500
+ /**
501
+ * Determines if a field is required based on the Zod schema
502
+ */
503
+ isFieldRequired(schema, fieldPath) {
504
+ if (!schema || !fieldPath) {
505
+ return false;
506
+ }
507
+ try {
508
+ const zodObject = this.extractZodObject(schema);
509
+ if (!zodObject) return false;
510
+ const shape = zodObject.shape;
511
+ if (!shape || !shape[fieldPath]) return false;
512
+ const fieldSchema = shape[fieldPath];
513
+ if (!fieldSchema || !fieldSchema._def) return true;
514
+ const fieldDef = fieldSchema._def;
515
+ const typeName = fieldDef.typeName;
516
+ if (typeName === "ZodOptional") {
517
+ return false;
518
+ }
519
+ if (typeName === "ZodDefault") {
520
+ return false;
521
+ }
522
+ if (fieldDef.defaultValue !== void 0) {
523
+ return false;
524
+ }
525
+ return true;
526
+ } catch (error) {
527
+ this.logger.debug(
528
+ `Could not determine if field ${fieldPath} is required:`,
529
+ error
530
+ );
531
+ }
532
+ return false;
533
+ }
534
+ /**
535
+ * Generates a description for the form
536
+ */
537
+ generateFormDescription(toolName, fieldCount) {
538
+ if (fieldCount === 0) {
539
+ return "Please provide the required information to continue with your request.";
540
+ }
541
+ return `Please provide the following ${fieldCount} required field${fieldCount !== 1 ? "s" : ""} to continue with your request.`;
542
+ }
543
+ /**
544
+ * Generates JSON Schema and uiSchema from a Zod schema for use with @rjsf/core
545
+ * @param zodSchema The Zod schema to convert
546
+ * @param partialInput Existing input data to filter out fields that already have values
547
+ * @param missingFields Set of fields that are missing and should be shown
548
+ * @returns Object containing jsonSchema and uiSchema
549
+ */
550
+ generateJsonSchemaForm(zodSchema, partialInput, missingFields) {
551
+ const fullJsonSchema = zodToJsonSchema(zodSchema, {
552
+ target: "jsonSchema7"
553
+ });
554
+ const uiSchema = {};
555
+ let jsonSchema = fullJsonSchema;
556
+ if (missingFields && missingFields.size > 0) {
557
+ const fullSchemaAsObject = fullJsonSchema;
558
+ if (fullSchemaAsObject.properties && typeof fullSchemaAsObject.properties === "object") {
559
+ const filteredSchema = {
560
+ ...fullSchemaAsObject,
561
+ type: "object",
562
+ properties: {},
563
+ required: []
564
+ };
565
+ let fieldsAdded = 0;
566
+ missingFields.forEach((fieldName) => {
567
+ if (fullSchemaAsObject.properties && fullSchemaAsObject.properties[fieldName]) {
568
+ filteredSchema.properties[fieldName] = fullSchemaAsObject.properties[fieldName];
569
+ fieldsAdded++;
570
+ }
571
+ });
572
+ if (Array.isArray(fullSchemaAsObject.required)) {
573
+ filteredSchema.required = fullSchemaAsObject.required.filter(
574
+ (field) => missingFields.has(field)
575
+ );
576
+ }
577
+ if (fieldsAdded > 0) {
578
+ jsonSchema = filteredSchema;
579
+ }
580
+ }
581
+ }
582
+ const fieldNames = this.extractFieldsFromSchema(zodSchema);
583
+ fieldNames.forEach((fieldName) => {
584
+ const isRequired = this.isFieldRequired(zodSchema, fieldName);
585
+ const priority = this.getFieldPriority(fieldName, void 0, isRequired);
586
+ const lower = fieldName.toLowerCase();
587
+ if (lower === "attributes" || lower === "metadata" || lower === "properties") {
588
+ uiSchema[fieldName] = {
589
+ "ui:options": {
590
+ collapsible: true,
591
+ collapsed: true
592
+ }
593
+ };
594
+ }
595
+ switch (priority) {
596
+ case "essential":
597
+ if (isRequired) {
598
+ uiSchema[fieldName] = {
599
+ ...uiSchema[fieldName],
600
+ "ui:help": "Required field"
601
+ };
602
+ }
603
+ break;
604
+ case "advanced":
605
+ case "expert":
606
+ uiSchema[fieldName] = {
607
+ ...uiSchema[fieldName],
608
+ "ui:options": {
609
+ ...uiSchema[fieldName]?.["ui:options"],
610
+ collapsed: true
611
+ }
612
+ };
613
+ break;
614
+ }
615
+ });
616
+ return { jsonSchema, uiSchema };
44
617
  }
45
618
  }
46
619
  export {
47
- TransferHbarTool
620
+ FormGenerator
48
621
  };
49
622
  //# sourceMappingURL=index18.js.map