@hashgraphonline/conversational-agent 0.2.217 → 0.2.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.
@@ -1,118 +1,325 @@
1
- import { BaseHederaQueryTool } from "hedera-agent-kit";
2
1
  import { z } from "zod";
3
- import { promisify } from "util";
4
- import fs from "fs";
5
- import { getUploadPostageBatchId, errorHasStatus, getErrorMessage, getResponseWithStructuredContent } from "./index62.js";
6
- import { DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB, GATEWAY_TAG_ERROR_MESSAGE, NOT_FOUND_STATUS, BAD_REQUEST_STATUS } from "./index63.js";
7
- const UploadFileSchema = z.object({
8
- data: z.string(),
9
- isPath: z.boolean(),
10
- redundancyLevel: z.number().optional(),
11
- postageBatchId: z.string().optional()
12
- });
13
- class UploadFileTool extends BaseHederaQueryTool {
14
- constructor(params) {
15
- const { bee, config, ...rest } = params;
16
- super(rest);
17
- this.name = "swarm-upload-file";
18
- this.description = `Upload a file to Swarm.
19
- data: base64 encoded file content or file path.
20
- isPath: Wether the data parameter is a path.
21
- redundancyLevel: Redundancy level for fault tolerance (higher values provide better fault tolerance but increase storage overhead). 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid.
22
- postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;
23
- this.namespace = "swarm";
24
- this.specificInputSchema = UploadFileSchema;
25
- this.bee = bee;
26
- this.config = config;
27
- }
28
- async executeQuery(input) {
29
- const { data, isPath, redundancyLevel: inputRedundancyLevel, postageBatchId: inputPostageBatchId } = input;
30
- if (!data) {
31
- this.logger.error(
32
- "Missing required parameter: data."
33
- );
34
- throw new Error("Missing required parameter: data.");
2
+ import { Logger } from "@hashgraphonline/standards-sdk";
3
+ import { wrapToolWithFormValidation } from "./index33.js";
4
+ import { FormGenerator } from "./index11.js";
5
+ import { fieldGuidanceRegistry } from "./index14.js";
6
+ import { isFormValidatable } from "@hashgraphonline/standards-agent-kit";
7
+ class ToolRegistry {
8
+ constructor(logger) {
9
+ this.tools = /* @__PURE__ */ new Map();
10
+ this.formGenerator = new FormGenerator();
11
+ this.logger = logger || new Logger({ module: "ToolRegistry" });
12
+ }
13
+ /**
14
+ * Register a tool with the registry
15
+ */
16
+ registerTool(tool, options = {}) {
17
+ const capabilities = this.analyzeToolCapabilities(tool);
18
+ const metadata = {
19
+ name: tool.name,
20
+ version: "1.0.0",
21
+ category: options.metadata?.category || "core",
22
+ description: tool.description,
23
+ capabilities,
24
+ dependencies: [],
25
+ schema: tool.schema,
26
+ ...options.metadata
27
+ };
28
+ try {
29
+ if (!metadata.entityResolutionPreferences) {
30
+ const schemaRecord = tool.schema;
31
+ const rawPrefs = schemaRecord && typeof schemaRecord === "object" && schemaRecord["_entityResolutionPreferences"];
32
+ if (rawPrefs && typeof rawPrefs === "object") {
33
+ metadata.entityResolutionPreferences = rawPrefs;
34
+ }
35
+ }
36
+ } catch {
35
37
  }
36
- let postageBatchId = "";
37
38
  try {
38
- postageBatchId = await getUploadPostageBatchId(
39
- inputPostageBatchId,
40
- this.bee,
41
- this.config
39
+ const schemaRecord = tool.schema;
40
+ const schemaDef = schemaRecord && schemaRecord._def;
41
+ if (schemaDef?.typeName === "ZodObject") {
42
+ const shape = typeof schemaDef.shape === "function" ? schemaDef.shape?.() || {} : schemaDef.shape || {};
43
+ const metadataField = shape["metadata"];
44
+ const isStringArray = !!metadataField && metadataField._def?.typeName === "ZodArray" && metadataField._def?.type?._def?.typeName === "ZodString";
45
+ if (isStringArray && typeof tool.description === "string") {
46
+ if (!metadata.entityResolutionPreferences) {
47
+ metadata.entityResolutionPreferences = {
48
+ inscription: "hrl"
49
+ };
50
+ }
51
+ const note = " NOTE: When referencing inscriptions or media, provide canonical Hashlink Resource Locators (e.g., hcs://<standard>/<topicId>) rather than external URLs or embedded JSON.";
52
+ if (!tool.description.includes("Hashlink Resource Locators")) {
53
+ tool.description = `${tool.description}${note}`;
54
+ }
55
+ }
56
+ }
57
+ } catch {
58
+ }
59
+ let finalTool = tool;
60
+ let wrapper;
61
+ if (this.shouldWrapTool(tool, capabilities, options)) {
62
+ wrapper = wrapToolWithFormValidation(
63
+ tool,
64
+ this.formGenerator,
65
+ {
66
+ requireAllFields: false,
67
+ skipFields: ["metaOptions"],
68
+ ...options.wrapperConfig
69
+ }
42
70
  );
43
- } catch (error) {
44
- let errorMessage = "Upload file failed.";
45
- if (error instanceof Error) {
46
- errorMessage = error.message;
71
+ finalTool = wrapper;
72
+ }
73
+ try {
74
+ if (metadata.entityResolutionPreferences) {
75
+ finalTool["entityResolutionPreferences"] = metadata.entityResolutionPreferences;
76
+ }
77
+ } catch {
78
+ }
79
+ const entry = {
80
+ tool: finalTool,
81
+ metadata,
82
+ wrapper,
83
+ originalTool: tool,
84
+ options: {
85
+ priority: capabilities.priority,
86
+ capability: "basic",
87
+ // Default capability
88
+ enabled: true,
89
+ // All tools are enabled by default
90
+ namespace: metadata.category
47
91
  }
48
- this.logger.error(errorMessage);
49
- throw new Error(errorMessage);
50
- }
51
- let binaryData;
52
- let name;
53
- if (isPath) {
54
- try {
55
- binaryData = await promisify(fs.readFile)(data);
56
- } catch (fileError) {
57
- this.logger.error(
58
- `Unable to read file at path: ${data}.`,
59
- fileError
60
- );
61
- throw new Error(`Unable to read file at path: ${data}.`);
92
+ };
93
+ this.tools.set(tool.name, entry);
94
+ try {
95
+ const metaFG = metadata.fieldGuidance;
96
+ if (metaFG) {
97
+ fieldGuidanceRegistry.registerToolConfiguration(metaFG);
98
+ }
99
+ const provider = metadata.fieldGuidanceProvider;
100
+ if (provider) {
101
+ const pattern = metaFG?.toolPattern ?? tool.name;
102
+ fieldGuidanceRegistry.registerToolProvider(pattern, provider, {
103
+ id: `${tool.name}:field-guidance-provider`,
104
+ priority: 0
105
+ });
62
106
  }
63
- name = data.split("/").pop();
64
- } else {
65
- binaryData = Buffer.from(data, "base64");
66
- }
67
- const redundancyLevel = inputRedundancyLevel;
68
- const options = {};
69
- const deferredUploadSizeThreshold = Number(this.config.deferredUploadSizeThresholdMB) || DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB;
70
- const deferred = binaryData.length > deferredUploadSizeThreshold * 1024 * 1024;
71
- options.deferred = deferred;
72
- if (redundancyLevel) {
73
- options.redundancyLevel = redundancyLevel;
74
- }
75
- let message = "File successfully uploaded to Swarm";
76
- let tagId = void 0;
77
- if (deferred) {
78
- try {
79
- const tag = await this.bee.createTag();
80
- options.tag = tag.uid;
81
- tagId = tag.uid.toString();
82
- message = "File upload started in deferred mode. Use query_upload_progress to track progress.";
83
- } catch (error) {
84
- if (errorHasStatus(error, NOT_FOUND_STATUS)) {
85
- this.logger.error(
86
- GATEWAY_TAG_ERROR_MESSAGE,
87
- error
88
- );
89
- throw new Error(GATEWAY_TAG_ERROR_MESSAGE);
107
+ } catch {
108
+ }
109
+ }
110
+ /**
111
+ * Get a tool by name
112
+ */
113
+ getTool(name) {
114
+ return this.tools.get(name) || null;
115
+ }
116
+ /**
117
+ * Get tools by capability
118
+ */
119
+ getToolsByCapability(capability, value) {
120
+ const results = [];
121
+ for (const entry of this.tools.values()) {
122
+ if (value !== void 0) {
123
+ if (entry.metadata.capabilities[capability] === value) {
124
+ results.push(entry);
90
125
  }
126
+ } else if (entry.metadata.capabilities[capability]) {
127
+ results.push(entry);
91
128
  }
92
129
  }
93
- let result;
94
- try {
95
- result = await this.bee.uploadFile(postageBatchId, binaryData, name, options);
96
- } catch (error) {
97
- let errorMessage = "Unable to upload file.";
98
- if (errorHasStatus(error, BAD_REQUEST_STATUS)) {
99
- errorMessage = getErrorMessage(error);
130
+ return results;
131
+ }
132
+ /**
133
+ * Get tools by query
134
+ */
135
+ getToolsByQuery(query) {
136
+ const results = [];
137
+ for (const entry of this.tools.values()) {
138
+ let matches = true;
139
+ if (query.name && entry.metadata.name !== query.name) {
140
+ matches = false;
100
141
  }
101
- this.logger.error(
102
- errorMessage,
103
- error
104
- );
105
- throw new Error(errorMessage);
142
+ if (query.category && entry.metadata.category !== query.category) {
143
+ matches = false;
144
+ }
145
+ if (query.capabilities) {
146
+ for (const [key, value] of Object.entries(query.capabilities)) {
147
+ if (entry.metadata.capabilities[key] !== value) {
148
+ matches = false;
149
+ break;
150
+ }
151
+ }
152
+ }
153
+ if (matches) {
154
+ results.push(entry);
155
+ }
156
+ }
157
+ return results;
158
+ }
159
+ /**
160
+ * Get all registered tools
161
+ */
162
+ getAllTools() {
163
+ return Array.from(this.tools.values()).map((entry) => entry.tool);
164
+ }
165
+ /**
166
+ * Get all registry entries
167
+ */
168
+ getAllRegistryEntries() {
169
+ return Array.from(this.tools.values());
170
+ }
171
+ /**
172
+ * Get all tool names
173
+ */
174
+ getToolNames() {
175
+ return Array.from(this.tools.keys());
176
+ }
177
+ /**
178
+ * Get tools by priority
179
+ */
180
+ getToolsByPriority(priority) {
181
+ return this.getToolsByCapability("priority", priority);
182
+ }
183
+ /**
184
+ * Get enabled tools (all tools are considered enabled by default)
185
+ */
186
+ getEnabledTools() {
187
+ return this.getAllRegistryEntries();
188
+ }
189
+ /**
190
+ * Get tools by namespace/category
191
+ */
192
+ getToolsByNamespace(namespace) {
193
+ if (!namespace) {
194
+ return this.getAllRegistryEntries();
195
+ }
196
+ return this.getToolsByQuery({ category: namespace });
197
+ }
198
+ /**
199
+ * Check if registry has capability
200
+ */
201
+ hasCapability(capability) {
202
+ for (const entry of this.tools.values()) {
203
+ if (entry.metadata.capabilities[capability]) {
204
+ return true;
205
+ }
206
+ }
207
+ return false;
208
+ }
209
+ /**
210
+ * Update tool options (metadata)
211
+ */
212
+ updateToolOptions(name, options) {
213
+ const entry = this.tools.get(name);
214
+ if (!entry) {
215
+ return false;
216
+ }
217
+ entry.metadata = { ...entry.metadata, ...options };
218
+ return true;
219
+ }
220
+ /**
221
+ * Check if a tool is registered
222
+ */
223
+ hasTool(name) {
224
+ return this.tools.has(name);
225
+ }
226
+ /**
227
+ * Unregister a tool
228
+ */
229
+ unregisterTool(name) {
230
+ return this.tools.delete(name);
231
+ }
232
+ /**
233
+ * Clear all tools
234
+ */
235
+ clear() {
236
+ this.tools.clear();
237
+ }
238
+ /**
239
+ * Analyze tool capabilities
240
+ */
241
+ analyzeToolCapabilities(tool) {
242
+ const implementsFormValidatable = isFormValidatable(tool);
243
+ const hasRenderConfig = this.hasRenderConfig(tool);
244
+ const isZodObjectLike = this.isZodObjectLike(tool.schema);
245
+ const supportsFormValidation = implementsFormValidatable || hasRenderConfig;
246
+ const requiresWrapper = supportsFormValidation && isZodObjectLike;
247
+ let priority = "medium";
248
+ let category = "core";
249
+ if (supportsFormValidation && requiresWrapper) {
250
+ priority = "critical";
251
+ } else if (supportsFormValidation) {
252
+ priority = "high";
253
+ } else if (tool.description?.toLowerCase().includes("query") || tool.description?.toLowerCase().includes("search")) {
254
+ priority = "low";
255
+ }
256
+ const toolAsAny = tool;
257
+ if (tool.constructor.name.includes("MCP") || toolAsAny.isMCPTool) {
258
+ category = "mcp";
259
+ } else if (toolAsAny.isExtension || tool.constructor.name.includes("Extension")) {
260
+ category = "extension";
261
+ }
262
+ return {
263
+ supportsFormValidation,
264
+ requiresWrapper,
265
+ priority,
266
+ category
267
+ };
268
+ }
269
+ /**
270
+ * Check if tool has render configuration
271
+ */
272
+ hasRenderConfig(tool) {
273
+ const schema = tool.schema;
274
+ return !!(schema && schema._renderConfig);
275
+ }
276
+ /**
277
+ * Determine if tool should be wrapped
278
+ */
279
+ shouldWrapTool(tool, capabilities, options) {
280
+ if (options.skipWrapper) {
281
+ return false;
282
+ }
283
+ if (options.forceWrapper) {
284
+ return true;
285
+ }
286
+ return capabilities.requiresWrapper;
287
+ }
288
+ /**
289
+ * Check if schema is ZodObject-like
290
+ */
291
+ isZodObjectLike(schema) {
292
+ if (!schema || typeof schema !== "object") {
293
+ return false;
294
+ }
295
+ const schemaRecord = schema;
296
+ const schemaDef = schemaRecord._def;
297
+ return schema instanceof z.ZodObject || schemaDef?.typeName === "ZodObject" || "shape" in schemaRecord && typeof schemaRecord.shape === "object";
298
+ }
299
+ /**
300
+ * Get statistics about the registry
301
+ */
302
+ getStatistics() {
303
+ const stats = {
304
+ totalTools: this.tools.size,
305
+ wrappedTools: 0,
306
+ unwrappedTools: 0,
307
+ categoryCounts: { core: 0, extension: 0, mcp: 0 },
308
+ priorityCounts: { low: 0, medium: 0, high: 0, critical: 0 }
309
+ };
310
+ for (const entry of this.tools.values()) {
311
+ if (entry.wrapper) {
312
+ stats.wrappedTools++;
313
+ } else {
314
+ stats.unwrappedTools++;
315
+ }
316
+ stats.categoryCounts[entry.metadata.category]++;
317
+ stats.priorityCounts[entry.metadata.capabilities.priority]++;
106
318
  }
107
- return getResponseWithStructuredContent({
108
- reference: result.reference.toString(),
109
- url: this.bee.url + "/bzz/" + result.reference.toString(),
110
- message,
111
- tagId
112
- });
319
+ return stats;
113
320
  }
114
321
  }
115
322
  export {
116
- UploadFileTool
323
+ ToolRegistry
117
324
  };
118
325
  //# sourceMappingURL=index58.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index58.js","sources":["../../src/plugins/community/swarm/tools/UploadFileTool.ts"],"sourcesContent":["import {\r\n BaseHederaQueryTool,\r\n HederaAgentKit,\r\n type GenericPluginContext,\r\n} from \"hedera-agent-kit\";\r\nimport { Bee, FileUploadOptions } from \"@ethersphere/bee-js\";\r\nimport { z } from \"zod\";\r\nimport { promisify } from \"util\";\r\nimport fs from \"fs\";\r\nimport {\r\n errorHasStatus,\r\n getErrorMessage,\r\n getResponseWithStructuredContent,\r\n getUploadPostageBatchId,\r\n ToolResponse,\r\n} from \"../utils\";\r\nimport { BAD_REQUEST_STATUS, DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB, GATEWAY_TAG_ERROR_MESSAGE, NOT_FOUND_STATUS } from \"../constants\";\r\nimport { SwarmConfig } from \"../config\";\r\n\r\nconst UploadFileSchema = z.object({\r\n data: z.string(),\r\n isPath: z.boolean(),\r\n redundancyLevel: z.number().optional(),\r\n postageBatchId: z.string().optional(),\r\n});\r\n\r\nexport class UploadFileTool extends BaseHederaQueryTool<typeof UploadFileSchema> {\r\n name = \"swarm-upload-file\";\r\n description = `Upload a file to Swarm.\r\n data: base64 encoded file content or file path.\r\n isPath: Wether the data parameter is a path.\r\n redundancyLevel: Redundancy level for fault tolerance (higher values provide better fault tolerance but increase storage overhead). 0 - none, 1 - medium, 2 - strong, 3 - insane, 4 - paranoid.\r\n postageBatchId: The postage stamp batch ID which will be used to perform the upload, if it is provided.`;\r\n namespace = \"swarm\";\r\n specificInputSchema = UploadFileSchema;\r\n bee: Bee;\r\n config: SwarmConfig;\r\n\r\n constructor(params: {\r\n hederaKit: HederaAgentKit;\r\n config: SwarmConfig;\r\n logger?: GenericPluginContext['logger'];\r\n bee: Bee;\r\n }) {\r\n const { bee, config, ...rest } = params;\r\n super(rest);\r\n this.bee = bee;\r\n this.config = config;\r\n }\r\n \r\n protected async executeQuery(\r\n input: z.infer<typeof UploadFileSchema>\r\n ): Promise<ToolResponse | string> {\r\n const { data, isPath, redundancyLevel: inputRedundancyLevel, postageBatchId: inputPostageBatchId } = input;\r\n\r\n if (!data) {\r\n this.logger.error(\r\n 'Missing required parameter: data.'\r\n );\r\n\r\n throw new Error('Missing required parameter: data.');\r\n }\r\n\r\n let postageBatchId = \"\";\r\n\r\n try {\r\n postageBatchId = await getUploadPostageBatchId(\r\n inputPostageBatchId,\r\n this.bee,\r\n this.config,\r\n );\r\n } catch (error) {\r\n let errorMessage = 'Upload file failed.';\r\n if (error instanceof Error) {\r\n errorMessage = error.message;\r\n }\r\n this.logger.error(errorMessage);\r\n\r\n throw new Error(errorMessage);\r\n }\r\n\r\n let binaryData: Buffer;\r\n let name: string | undefined;\r\n\r\n if (isPath) {\r\n // Read file from path\r\n try {\r\n binaryData = await promisify(fs.readFile)(data);\r\n } catch (fileError) {\r\n this.logger.error(\r\n `Unable to read file at path: ${data}.`,\r\n fileError\r\n );\r\n\r\n throw new Error(`Unable to read file at path: ${data}.`);\r\n }\r\n\r\n name = data.split(\"/\").pop();\r\n } else {\r\n binaryData = Buffer.from(data, \"base64\");\r\n }\r\n\r\n const redundancyLevel = inputRedundancyLevel;\r\n const options: FileUploadOptions = {};\r\n const deferredUploadSizeThreshold = Number(this.config.deferredUploadSizeThresholdMB) ||\r\n DEFAULT_DEFERRED_UPLOAD_SIZE_THRESHOLD_MB;\r\n const deferred =\r\n binaryData.length > deferredUploadSizeThreshold * 1024 * 1024;\r\n options.deferred = deferred;\r\n if (redundancyLevel) {\r\n options.redundancyLevel = redundancyLevel;\r\n }\r\n\r\n let message = \"File successfully uploaded to Swarm\";\r\n let tagId: string | undefined = undefined;\r\n // Create tag for deferred uploads or when explicitly requested\r\n if (deferred) {\r\n try {\r\n const tag = await this.bee.createTag();\r\n options.tag = tag.uid;\r\n tagId = tag.uid.toString();\r\n message =\r\n \"File upload started in deferred mode. Use query_upload_progress to track progress.\";\r\n } catch (error) {\r\n if (errorHasStatus(error, NOT_FOUND_STATUS)) {\r\n this.logger.error(\r\n GATEWAY_TAG_ERROR_MESSAGE,\r\n error\r\n );\r\n\r\n throw new Error(GATEWAY_TAG_ERROR_MESSAGE);\r\n }\r\n }\r\n }\r\n\r\n let result;\r\n\r\n try {\r\n // Start the deferred upload\r\n result = await this.bee.uploadFile(postageBatchId, binaryData, name, options);\r\n } catch (error) {\r\n let errorMessage = 'Unable to upload file.';\r\n\r\n if (errorHasStatus(error, BAD_REQUEST_STATUS)) {\r\n errorMessage = getErrorMessage(error);\r\n }\r\n\r\n this.logger.error(\r\n errorMessage,\r\n error\r\n );\r\n \r\n throw new Error(errorMessage);\r\n }\r\n\r\n return getResponseWithStructuredContent({\r\n reference: result.reference.toString(),\r\n url: this.bee.url + \"/bzz/\" + result.reference.toString(),\r\n message,\r\n tagId,\r\n });\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index58.js","sources":["../../src/core/tool-registry.ts"],"sourcesContent":["import { StructuredTool } from '@langchain/core/tools';\nimport { z } from 'zod';\nimport { Logger } from '@hashgraphonline/standards-sdk';\nimport {\n FormValidatingToolWrapper,\n wrapToolWithFormValidation,\n} from '../langchain/form-validating-tool-wrapper';\nimport { FormGenerator } from '../forms/form-generator';\nimport {\n fieldGuidanceRegistry,\n} from '../forms/field-guidance-registry';\nimport type {\n ToolFieldConfiguration as FG_ToolFieldConfiguration,\n FieldGuidanceProvider as FG_FieldGuidanceProvider,\n} from '../forms/field-guidance-registry';\nimport { isFormValidatable } from '@hashgraphonline/standards-agent-kit';\n\n/**\n * Tool capabilities configuration for registry entries\n */\nexport interface ToolCapabilities {\n supportsFormValidation: boolean;\n requiresWrapper: boolean;\n priority: 'low' | 'medium' | 'high' | 'critical';\n category: 'core' | 'extension' | 'mcp';\n}\n\n/**\n * Entity resolution format preferences for tools\n */\nexport interface EntityResolutionPreferences {\n inscription?: 'hrl' | 'topicId' | 'metadata' | 'any';\n token?: 'tokenId' | 'address' | 'symbol' | 'any';\n nft?: 'serialNumber' | 'metadata' | 'hrl' | 'any';\n account?: 'accountId' | 'alias' | 'evmAddress' | 'any';\n}\n\n/**\n * Tool metadata for comprehensive tool information\n */\nexport interface ToolMetadata {\n name: string;\n version: string;\n category: ToolCapabilities['category'];\n description: string;\n capabilities: ToolCapabilities;\n dependencies: string[];\n schema: unknown;\n entityResolutionPreferences?: EntityResolutionPreferences;\n fieldGuidance?: FG_ToolFieldConfiguration;\n fieldGuidanceProvider?: FG_FieldGuidanceProvider;\n}\n\n/**\n * Registry entry containing tool instance and metadata\n */\nexport interface ToolRegistryEntry {\n tool: StructuredTool;\n metadata: ToolMetadata;\n wrapper?: FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>> | undefined;\n originalTool: StructuredTool;\n options?: {\n priority?: ToolCapabilities['priority'];\n capability?: string;\n enabled?: boolean;\n namespace?: string;\n };\n}\n\n/**\n * Options for tool registration\n */\nexport interface ToolRegistrationOptions {\n forceWrapper?: boolean;\n skipWrapper?: boolean;\n wrapperConfig?: {\n requireAllFields?: boolean;\n skipFields?: string[];\n };\n metadata?: Partial<ToolMetadata>;\n}\n\n/**\n * Query interface for finding tools\n */\nexport interface ToolQuery {\n name?: string;\n category?: ToolMetadata['category'];\n capabilities?: Partial<ToolCapabilities>;\n}\n\n/**\n * Centralized tool registry for managing tool lifecycle\n */\nexport class ToolRegistry {\n private tools = new Map<string, ToolRegistryEntry>();\n private formGenerator: FormGenerator;\n private logger: Logger;\n\n constructor(logger?: Logger) {\n this.formGenerator = new FormGenerator();\n this.logger = logger || new Logger({ module: 'ToolRegistry' });\n }\n\n /**\n * Register a tool with the registry\n */\n registerTool(\n tool: StructuredTool,\n options: ToolRegistrationOptions = {}\n ): void {\n const capabilities = this.analyzeToolCapabilities(tool);\n const metadata: ToolMetadata = {\n name: tool.name,\n version: '1.0.0',\n category: options.metadata?.category || 'core',\n description: tool.description,\n capabilities,\n dependencies: [],\n schema: tool.schema,\n ...options.metadata,\n };\n\n try {\n if (!metadata.entityResolutionPreferences) {\n const schemaRecord = tool.schema as unknown as Record<string, unknown>;\n const rawPrefs =\n schemaRecord &&\n typeof schemaRecord === 'object' &&\n (schemaRecord as Record<string, unknown>)[\n '_entityResolutionPreferences'\n ];\n if (rawPrefs && typeof rawPrefs === 'object') {\n metadata.entityResolutionPreferences = rawPrefs as unknown as EntityResolutionPreferences;\n }\n }\n } catch {\n }\n\n try {\n const schemaRecord = tool.schema as unknown as Record<string, unknown>;\n const schemaDef = (schemaRecord && (schemaRecord as Record<string, unknown>)._def) as\n | { typeName?: string; shape?: unknown }\n | undefined;\n if (schemaDef?.typeName === 'ZodObject') {\n const shape: Record<string, unknown> =\n typeof (schemaDef as { shape?: () => Record<string, unknown> }).shape === 'function'\n ? ((schemaDef as { shape: () => Record<string, unknown> }).shape?.() || {})\n : ((schemaDef as { shape?: Record<string, unknown> }).shape || {});\n\n const metadataField = shape['metadata'] as\n | { _def?: { typeName?: string; type?: { _def?: { typeName?: string } } } }\n | undefined;\n const isStringArray =\n !!metadataField &&\n metadataField._def?.typeName === 'ZodArray' &&\n metadataField._def?.type?._def?.typeName === 'ZodString';\n\n if (isStringArray && typeof tool.description === 'string') {\n if (!metadata.entityResolutionPreferences) {\n metadata.entityResolutionPreferences = {\n inscription: 'hrl',\n } as EntityResolutionPreferences;\n }\n const note =\n ' NOTE: When referencing inscriptions or media, provide canonical Hashlink Resource Locators (e.g., hcs://<standard>/<topicId>) rather than external URLs or embedded JSON.';\n if (!tool.description.includes('Hashlink Resource Locators')) {\n (tool as unknown as { description: string }).description = `${tool.description}${note}`;\n }\n }\n }\n } catch {}\n\n let finalTool: StructuredTool = tool;\n let wrapper:\n | FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>>\n | undefined;\n\n if (this.shouldWrapTool(tool, capabilities, options)) {\n wrapper = wrapToolWithFormValidation(\n tool as StructuredTool<z.ZodObject<z.ZodRawShape>>,\n this.formGenerator,\n {\n requireAllFields: false,\n skipFields: ['metaOptions'],\n ...options.wrapperConfig,\n }\n ) as FormValidatingToolWrapper<z.ZodObject<z.ZodRawShape>>;\n finalTool = wrapper as StructuredTool;\n }\n\n try {\n if (metadata.entityResolutionPreferences) {\n (finalTool as unknown as Record<string, unknown>)[\n 'entityResolutionPreferences'\n ] = metadata.entityResolutionPreferences;\n }\n } catch {\n }\n\n const entry: ToolRegistryEntry = {\n tool: finalTool,\n metadata,\n wrapper,\n originalTool: tool,\n options: {\n priority: capabilities.priority,\n capability: 'basic', // Default capability\n enabled: true, // All tools are enabled by default\n namespace: metadata.category,\n },\n };\n\n this.tools.set(tool.name, entry);\n\n try {\n const metaFG = metadata.fieldGuidance as FG_ToolFieldConfiguration | undefined;\n if (metaFG) {\n fieldGuidanceRegistry.registerToolConfiguration(metaFG);\n }\n const provider = metadata.fieldGuidanceProvider as FG_FieldGuidanceProvider | undefined;\n if (provider) {\n const pattern = metaFG?.toolPattern ?? tool.name;\n fieldGuidanceRegistry.registerToolProvider(pattern, provider, {\n id: `${tool.name}:field-guidance-provider`,\n priority: 0,\n });\n }\n } catch {}\n }\n\n /**\n * Get a tool by name\n */\n getTool(name: string): ToolRegistryEntry | null {\n return this.tools.get(name) || null;\n }\n\n /**\n * Get tools by capability\n */\n getToolsByCapability(\n capability: keyof ToolCapabilities,\n value?: unknown\n ): ToolRegistryEntry[] {\n const results: ToolRegistryEntry[] = [];\n\n for (const entry of this.tools.values()) {\n if (value !== undefined) {\n if (entry.metadata.capabilities[capability] === value) {\n results.push(entry);\n }\n } else if (entry.metadata.capabilities[capability]) {\n results.push(entry);\n }\n }\n\n return results;\n }\n\n /**\n * Get tools by query\n */\n getToolsByQuery(query: ToolQuery): ToolRegistryEntry[] {\n const results: ToolRegistryEntry[] = [];\n\n for (const entry of this.tools.values()) {\n let matches = true;\n\n if (query.name && entry.metadata.name !== query.name) {\n matches = false;\n }\n\n if (query.category && entry.metadata.category !== query.category) {\n matches = false;\n }\n\n if (query.capabilities) {\n for (const [key, value] of Object.entries(query.capabilities)) {\n if (\n entry.metadata.capabilities[key as keyof ToolCapabilities] !== value\n ) {\n matches = false;\n break;\n }\n }\n }\n\n if (matches) {\n results.push(entry);\n }\n }\n\n return results;\n }\n\n /**\n * Get all registered tools\n */\n getAllTools(): StructuredTool[] {\n return Array.from(this.tools.values()).map((entry) => entry.tool);\n }\n\n /**\n * Get all registry entries\n */\n getAllRegistryEntries(): ToolRegistryEntry[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Get all tool names\n */\n getToolNames(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * Get tools by priority\n */\n getToolsByPriority(priority: ToolCapabilities['priority']): ToolRegistryEntry[] {\n return this.getToolsByCapability('priority', priority);\n }\n\n /**\n * Get enabled tools (all tools are considered enabled by default)\n */\n getEnabledTools(): ToolRegistryEntry[] {\n return this.getAllRegistryEntries();\n }\n\n /**\n * Get tools by namespace/category\n */\n getToolsByNamespace(namespace?: string): ToolRegistryEntry[] {\n if (!namespace) {\n return this.getAllRegistryEntries();\n }\n return this.getToolsByQuery({ category: namespace as ToolMetadata['category'] });\n }\n\n /**\n * Check if registry has capability\n */\n hasCapability(capability: keyof ToolCapabilities): boolean {\n for (const entry of this.tools.values()) {\n if (entry.metadata.capabilities[capability]) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Update tool options (metadata)\n */\n updateToolOptions(name: string, options: Partial<ToolMetadata>): boolean {\n const entry = this.tools.get(name);\n if (!entry) {\n return false;\n }\n\n entry.metadata = { ...entry.metadata, ...options };\n return true;\n }\n\n /**\n * Check if a tool is registered\n */\n hasTool(name: string): boolean {\n return this.tools.has(name);\n }\n\n /**\n * Unregister a tool\n */\n unregisterTool(name: string): boolean {\n return this.tools.delete(name);\n }\n\n /**\n * Clear all tools\n */\n clear(): void {\n this.tools.clear();\n }\n\n /**\n * Analyze tool capabilities\n */\n private analyzeToolCapabilities(tool: StructuredTool): ToolCapabilities {\n const implementsFormValidatable = isFormValidatable(tool);\n const hasRenderConfig = this.hasRenderConfig(tool);\n const isZodObjectLike = this.isZodObjectLike(tool.schema);\n\n const supportsFormValidation = implementsFormValidatable || hasRenderConfig;\n const requiresWrapper = supportsFormValidation && isZodObjectLike;\n\n let priority: ToolCapabilities['priority'] = 'medium';\n let category: ToolCapabilities['category'] = 'core';\n\n if (supportsFormValidation && requiresWrapper) {\n priority = 'critical';\n } else if (supportsFormValidation) {\n priority = 'high';\n } else if (\n tool.description?.toLowerCase().includes('query') ||\n tool.description?.toLowerCase().includes('search')\n ) {\n priority = 'low';\n }\n\n const toolAsAny = tool as unknown as Record<string, unknown>;\n if (tool.constructor.name.includes('MCP') || toolAsAny.isMCPTool) {\n category = 'mcp';\n } else if (\n toolAsAny.isExtension ||\n tool.constructor.name.includes('Extension')\n ) {\n category = 'extension';\n }\n\n return {\n supportsFormValidation,\n requiresWrapper,\n priority,\n category,\n };\n }\n\n /**\n * Check if tool has render configuration\n */\n private hasRenderConfig(tool: StructuredTool): boolean {\n const schema = tool.schema as Record<string, unknown>;\n return !!(schema && schema._renderConfig);\n }\n\n /**\n * Determine if tool should be wrapped\n */\n private shouldWrapTool(\n tool: StructuredTool,\n capabilities: ToolCapabilities,\n options: ToolRegistrationOptions\n ): boolean {\n if (options.skipWrapper) {\n return false;\n }\n\n if (options.forceWrapper) {\n return true;\n }\n\n return capabilities.requiresWrapper;\n }\n\n /**\n * Check if schema is ZodObject-like\n */\n private isZodObjectLike(schema: unknown): boolean {\n if (!schema || typeof schema !== 'object') {\n return false;\n }\n\n const schemaRecord = schema as Record<string, unknown>;\n const schemaDef = schemaRecord._def as Record<string, unknown> | undefined;\n\n return (\n schema instanceof z.ZodObject ||\n schemaDef?.typeName === 'ZodObject' ||\n ('shape' in schemaRecord && typeof schemaRecord.shape === 'object')\n );\n }\n\n /**\n * Get statistics about the registry\n */\n getStatistics(): {\n totalTools: number;\n wrappedTools: number;\n unwrappedTools: number;\n categoryCounts: Record<ToolCapabilities['category'], number>;\n priorityCounts: Record<ToolCapabilities['priority'], number>;\n } {\n const stats = {\n totalTools: this.tools.size,\n wrappedTools: 0,\n unwrappedTools: 0,\n categoryCounts: { core: 0, extension: 0, mcp: 0 } as Record<\n ToolCapabilities['category'],\n number\n >,\n priorityCounts: { low: 0, medium: 0, high: 0, critical: 0 } as Record<\n ToolCapabilities['priority'],\n number\n >,\n };\n\n for (const entry of this.tools.values()) {\n if (entry.wrapper) {\n stats.wrappedTools++;\n } else {\n stats.unwrappedTools++;\n }\n\n stats.categoryCounts[entry.metadata.category]++;\n stats.priorityCounts[entry.metadata.capabilities.priority]++;\n }\n\n return stats;\n }\n}\n"],"names":[],"mappings":"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"}