@juspay/neurolink 7.14.1 → 7.14.3

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 (101) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli/commands/config.d.ts +66 -66
  3. package/dist/core/baseProvider.d.ts +12 -7
  4. package/dist/core/baseProvider.js +118 -125
  5. package/dist/core/constants.d.ts +5 -0
  6. package/dist/core/constants.js +6 -0
  7. package/dist/core/dynamicModels.d.ts +4 -4
  8. package/dist/core/factory.d.ts +2 -4
  9. package/dist/core/types.d.ts +8 -22
  10. package/dist/index.d.ts +19 -4
  11. package/dist/index.js +21 -0
  12. package/dist/lib/core/baseProvider.d.ts +12 -7
  13. package/dist/lib/core/baseProvider.js +118 -125
  14. package/dist/lib/core/constants.d.ts +5 -0
  15. package/dist/lib/core/constants.js +6 -0
  16. package/dist/lib/core/dynamicModels.d.ts +8 -8
  17. package/dist/lib/core/factory.d.ts +2 -4
  18. package/dist/lib/core/types.d.ts +8 -22
  19. package/dist/lib/index.d.ts +19 -4
  20. package/dist/lib/index.js +21 -0
  21. package/dist/lib/mcp/contracts/mcpContract.d.ts +6 -19
  22. package/dist/lib/mcp/externalServerManager.d.ts +2 -4
  23. package/dist/lib/mcp/externalServerManager.js +7 -8
  24. package/dist/lib/mcp/factory.d.ts +61 -7
  25. package/dist/lib/mcp/factory.js +36 -23
  26. package/dist/lib/mcp/mcpClientFactory.d.ts +2 -1
  27. package/dist/lib/mcp/mcpClientFactory.js +73 -26
  28. package/dist/lib/mcp/registry.d.ts +1 -1
  29. package/dist/lib/mcp/toolDiscoveryService.d.ts +1 -1
  30. package/dist/lib/mcp/toolDiscoveryService.js +50 -19
  31. package/dist/lib/mcp/toolRegistry.d.ts +23 -1
  32. package/dist/lib/mcp/toolRegistry.js +108 -17
  33. package/dist/lib/models/modelResolver.js +2 -1
  34. package/dist/lib/neurolink.d.ts +12 -8
  35. package/dist/lib/neurolink.js +130 -134
  36. package/dist/lib/providers/amazonBedrock.d.ts +2 -2
  37. package/dist/lib/providers/anthropic.d.ts +3 -3
  38. package/dist/lib/providers/googleAiStudio.d.ts +2 -2
  39. package/dist/lib/providers/mistral.d.ts +3 -3
  40. package/dist/lib/providers/ollama.d.ts +2 -2
  41. package/dist/lib/providers/openAI.d.ts +3 -3
  42. package/dist/lib/providers/openaiCompatible.d.ts +2 -2
  43. package/dist/lib/providers/sagemaker/client.d.ts +2 -5
  44. package/dist/lib/providers/sagemaker/language-model.d.ts +4 -6
  45. package/dist/lib/providers/sagemaker/parsers.js +5 -4
  46. package/dist/lib/sdk/toolRegistration.d.ts +6 -6
  47. package/dist/lib/sdk/toolRegistration.js +17 -56
  48. package/dist/lib/types/generateTypes.d.ts +9 -9
  49. package/dist/lib/types/streamTypes.d.ts +4 -4
  50. package/dist/lib/types/tools.d.ts +15 -7
  51. package/dist/lib/types/typeAliases.d.ts +412 -0
  52. package/dist/lib/types/typeAliases.js +48 -0
  53. package/dist/lib/utils/factoryProcessing.d.ts +2 -1
  54. package/dist/lib/utils/factoryProcessing.js +4 -3
  55. package/dist/lib/utils/parameterValidation.d.ts +97 -0
  56. package/dist/lib/utils/parameterValidation.js +452 -0
  57. package/dist/lib/utils/transformationUtils.d.ts +204 -0
  58. package/dist/lib/utils/transformationUtils.js +334 -0
  59. package/dist/lib/utils/typeUtils.d.ts +77 -0
  60. package/dist/lib/utils/typeUtils.js +97 -0
  61. package/dist/mcp/contracts/mcpContract.d.ts +6 -19
  62. package/dist/mcp/externalServerManager.d.ts +2 -4
  63. package/dist/mcp/externalServerManager.js +7 -8
  64. package/dist/mcp/factory.d.ts +61 -7
  65. package/dist/mcp/factory.js +36 -23
  66. package/dist/mcp/mcpClientFactory.d.ts +2 -1
  67. package/dist/mcp/mcpClientFactory.js +73 -26
  68. package/dist/mcp/registry.d.ts +1 -1
  69. package/dist/mcp/toolDiscoveryService.d.ts +1 -1
  70. package/dist/mcp/toolDiscoveryService.js +50 -19
  71. package/dist/mcp/toolRegistry.d.ts +23 -1
  72. package/dist/mcp/toolRegistry.js +108 -17
  73. package/dist/models/modelResolver.js +2 -1
  74. package/dist/neurolink.d.ts +12 -8
  75. package/dist/neurolink.js +130 -134
  76. package/dist/providers/amazonBedrock.d.ts +2 -2
  77. package/dist/providers/anthropic.d.ts +3 -3
  78. package/dist/providers/googleAiStudio.d.ts +2 -2
  79. package/dist/providers/mistral.d.ts +3 -3
  80. package/dist/providers/ollama.d.ts +2 -2
  81. package/dist/providers/openAI.d.ts +3 -3
  82. package/dist/providers/openaiCompatible.d.ts +2 -2
  83. package/dist/providers/sagemaker/client.d.ts +2 -5
  84. package/dist/providers/sagemaker/language-model.d.ts +4 -6
  85. package/dist/providers/sagemaker/parsers.js +5 -4
  86. package/dist/sdk/toolRegistration.d.ts +6 -6
  87. package/dist/sdk/toolRegistration.js +17 -56
  88. package/dist/types/generateTypes.d.ts +9 -9
  89. package/dist/types/streamTypes.d.ts +4 -4
  90. package/dist/types/tools.d.ts +15 -7
  91. package/dist/types/typeAliases.d.ts +412 -0
  92. package/dist/types/typeAliases.js +48 -0
  93. package/dist/utils/factoryProcessing.d.ts +2 -1
  94. package/dist/utils/factoryProcessing.js +4 -3
  95. package/dist/utils/parameterValidation.d.ts +97 -0
  96. package/dist/utils/parameterValidation.js +452 -0
  97. package/dist/utils/transformationUtils.d.ts +204 -0
  98. package/dist/utils/transformationUtils.js +334 -0
  99. package/dist/utils/typeUtils.d.ts +77 -0
  100. package/dist/utils/typeUtils.js +97 -0
  101. package/package.json +1 -1
@@ -0,0 +1,452 @@
1
+ /**
2
+ * Parameter Validation Utilities
3
+ * Provides consistent parameter validation across all tool interfaces
4
+ */
5
+ import { SYSTEM_LIMITS } from "../core/constants.js";
6
+ import { isNonNullObject } from "./typeUtils.js";
7
+ // ============================================================================
8
+ // VALIDATION ERROR TYPES
9
+ // ============================================================================
10
+ /**
11
+ * Custom error class for parameter validation failures
12
+ * Provides detailed information about validation errors including field context and suggestions
13
+ */
14
+ export class ValidationError extends Error {
15
+ field;
16
+ code;
17
+ suggestions;
18
+ /**
19
+ * Creates a new ValidationError
20
+ * @param message - Human-readable error message
21
+ * @param field - Name of the field that failed validation (optional)
22
+ * @param code - Error code for programmatic handling (optional)
23
+ * @param suggestions - Array of suggested fixes (optional)
24
+ */
25
+ constructor(message, field, code, suggestions) {
26
+ super(message);
27
+ this.field = field;
28
+ this.code = code;
29
+ this.suggestions = suggestions;
30
+ this.name = "ValidationError";
31
+ }
32
+ }
33
+ // ============================================================================
34
+ // BASIC PARAMETER VALIDATORS
35
+ // ============================================================================
36
+ /**
37
+ * Validate that a string parameter is present and non-empty
38
+ */
39
+ export function validateRequiredString(value, fieldName, minLength = 1) {
40
+ if (value === undefined || value === null) {
41
+ return new ValidationError(`${fieldName} is required`, fieldName, "REQUIRED_FIELD", [`Provide a valid ${fieldName.toLowerCase()}`]);
42
+ }
43
+ if (typeof value !== "string") {
44
+ return new ValidationError(`${fieldName} must be a string, received ${typeof value}`, fieldName, "INVALID_TYPE", [`Convert ${fieldName.toLowerCase()} to string format`]);
45
+ }
46
+ if (value.trim().length < minLength) {
47
+ return new ValidationError(`${fieldName} must be at least ${minLength} character${minLength > 1 ? "s" : ""} long`, fieldName, "MIN_LENGTH", [`Provide a meaningful ${fieldName.toLowerCase()}`]);
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * Validate that a number parameter is within acceptable range
53
+ */
54
+ export function validateNumberRange(value, fieldName, min, max, required = false) {
55
+ if (value === undefined || value === null) {
56
+ if (required) {
57
+ return new ValidationError(`${fieldName} is required`, fieldName, "REQUIRED_FIELD", [`Provide a number between ${min} and ${max}`]);
58
+ }
59
+ return null; // Optional field
60
+ }
61
+ if (typeof value !== "number" || isNaN(value)) {
62
+ return new ValidationError(`${fieldName} must be a valid number, received ${typeof value}`, fieldName, "INVALID_TYPE", [`Provide a number between ${min} and ${max}`]);
63
+ }
64
+ if (value < min || value > max) {
65
+ return new ValidationError(`${fieldName} must be between ${min} and ${max}, received ${value}`, fieldName, "OUT_OF_RANGE", [`Use a value between ${min} and ${max}`]);
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Validate that a function parameter is async and has correct signature
71
+ */
72
+ export function validateAsyncFunction(value, fieldName, expectedParams = []) {
73
+ if (typeof value !== "function") {
74
+ return new ValidationError(`${fieldName} must be a function, received ${typeof value}`, fieldName, "INVALID_TYPE", [
75
+ "Provide an async function",
76
+ `Expected signature: async (${expectedParams.join(", ")}) => Promise<unknown>`,
77
+ ]);
78
+ }
79
+ // Check if function appears to be async
80
+ const funcStr = value.toString();
81
+ const isAsync = funcStr.includes("async") || funcStr.includes("Promise");
82
+ if (!isAsync) {
83
+ return new ValidationError(`${fieldName} must be an async function that returns a Promise`, fieldName, "NOT_ASYNC", [
84
+ "Add 'async' keyword to function declaration",
85
+ "Return a Promise from the function",
86
+ `Example: async (${expectedParams.join(", ")}) => { return result; }`,
87
+ ]);
88
+ }
89
+ return null;
90
+ }
91
+ /**
92
+ * Validate object structure with required properties
93
+ */
94
+ export function validateObjectStructure(value, fieldName, requiredProperties, optionalProperties = []) {
95
+ if (!isNonNullObject(value)) {
96
+ return new ValidationError(`${fieldName} must be an object, received ${typeof value}`, fieldName, "INVALID_TYPE", [
97
+ `Provide an object with properties: ${requiredProperties.join(", ")}`,
98
+ ...(optionalProperties.length > 0
99
+ ? [`Optional properties: ${optionalProperties.join(", ")}`]
100
+ : []),
101
+ ]);
102
+ }
103
+ const obj = value;
104
+ const missingProps = requiredProperties.filter((prop) => !(prop in obj));
105
+ if (missingProps.length > 0) {
106
+ return new ValidationError(`${fieldName} is missing required properties: ${missingProps.join(", ")}`, fieldName, "MISSING_PROPERTIES", [`Add missing properties: ${missingProps.join(", ")}`]);
107
+ }
108
+ return null;
109
+ }
110
+ // ============================================================================
111
+ // TOOL-SPECIFIC VALIDATORS
112
+ // ============================================================================
113
+ /**
114
+ * Validate tool name according to naming conventions
115
+ */
116
+ export function validateToolName(name) {
117
+ const error = validateRequiredString(name, "Tool name", 1);
118
+ if (error) {
119
+ return error;
120
+ }
121
+ const toolName = name;
122
+ // Check naming conventions
123
+ if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(toolName)) {
124
+ return new ValidationError("Tool name must start with a letter and contain only letters, numbers, underscores, and hyphens", "name", "INVALID_FORMAT", [
125
+ "Use alphanumeric characters, underscores, and hyphens only",
126
+ "Start with a letter",
127
+ "Examples: 'calculateSum', 'data_processor', 'api-client'",
128
+ ]);
129
+ }
130
+ if (toolName.length > 64) {
131
+ return new ValidationError(`Tool name too long: ${toolName.length} characters (max: 64)`, "name", "MAX_LENGTH", ["Use a shorter, more concise name"]);
132
+ }
133
+ // Reserved names check
134
+ const reservedNames = ["execute", "validate", "setup", "init", "config"];
135
+ if (reservedNames.includes(toolName.toLowerCase())) {
136
+ return new ValidationError(`Tool name '${toolName}' is reserved`, "name", "RESERVED_NAME", ["Choose a different name", "Add a prefix or suffix to make it unique"]);
137
+ }
138
+ return null;
139
+ }
140
+ /**
141
+ * Validate tool description for clarity and usefulness
142
+ */
143
+ export function validateToolDescription(description) {
144
+ const error = validateRequiredString(description, "Tool description", 10);
145
+ if (error) {
146
+ return error;
147
+ }
148
+ const desc = description;
149
+ if (desc.length > 500) {
150
+ return new ValidationError(`Tool description too long: ${desc.length} characters (max: 500)`, "description", "MAX_LENGTH", ["Keep description concise and focused", "Use under 500 characters"]);
151
+ }
152
+ // Check for meaningful content
153
+ const meaningfulWords = desc.split(/\s+/).filter((word) => word.length > 2);
154
+ if (meaningfulWords.length < 3) {
155
+ return new ValidationError("Tool description should be more descriptive", "description", "TOO_BRIEF", [
156
+ "Explain what the tool does",
157
+ "Include expected parameters",
158
+ "Describe the return value",
159
+ ]);
160
+ }
161
+ return null;
162
+ }
163
+ /**
164
+ * Validate MCP tool structure comprehensively
165
+ */
166
+ export function validateMCPTool(tool) {
167
+ const errors = [];
168
+ const warnings = [];
169
+ const suggestions = [];
170
+ if (!isNonNullObject(tool)) {
171
+ errors.push(new ValidationError("Tool must be an object", "tool", "INVALID_TYPE", [
172
+ "Provide a valid tool object with name, description, and execute properties",
173
+ ]));
174
+ return { isValid: false, errors, warnings, suggestions };
175
+ }
176
+ const mcpTool = tool;
177
+ // Validate name
178
+ const nameError = validateToolName(mcpTool.name);
179
+ if (nameError) {
180
+ errors.push(nameError);
181
+ }
182
+ // Validate description
183
+ const descError = validateToolDescription(mcpTool.description);
184
+ if (descError) {
185
+ errors.push(descError);
186
+ }
187
+ // Validate execute function
188
+ const execError = validateAsyncFunction(mcpTool.execute, "execute function", [
189
+ "params",
190
+ "context",
191
+ ]);
192
+ if (execError) {
193
+ errors.push(execError);
194
+ }
195
+ // Additional MCP-specific validation
196
+ if (mcpTool.execute) {
197
+ try {
198
+ // Test execute function with mock data
199
+ const mockParams = {};
200
+ const mockContext = {
201
+ sessionId: "validation-test",
202
+ userId: "validation-user",
203
+ };
204
+ const result = mcpTool.execute(mockParams, mockContext);
205
+ const returnsPromise = result && typeof result === "object" && "then" in result;
206
+ if (!returnsPromise) {
207
+ errors.push(new ValidationError("Execute function must return a Promise", "execute", "NOT_PROMISE", [
208
+ "Ensure function returns a Promise<ToolResult>",
209
+ "Use async/await pattern",
210
+ "Return a result object with success property",
211
+ ]));
212
+ }
213
+ }
214
+ catch (error) {
215
+ warnings.push(`Execute function validation failed: ${error instanceof Error ? error.message : String(error)}`);
216
+ }
217
+ }
218
+ // Check optional properties
219
+ if (mcpTool.inputSchema && !isNonNullObject(mcpTool.inputSchema)) {
220
+ warnings.push("inputSchema should be an object if provided");
221
+ suggestions.push("Provide a valid JSON schema or Zod schema for input validation");
222
+ }
223
+ if (mcpTool.outputSchema && !isNonNullObject(mcpTool.outputSchema)) {
224
+ warnings.push("outputSchema should be an object if provided");
225
+ suggestions.push("Provide a valid JSON schema or Zod schema for output validation");
226
+ }
227
+ return {
228
+ isValid: errors.length === 0,
229
+ errors,
230
+ warnings,
231
+ suggestions,
232
+ };
233
+ }
234
+ // ============================================================================
235
+ // OPTIONS VALIDATORS
236
+ // ============================================================================
237
+ /**
238
+ * Validate text generation options
239
+ */
240
+ export function validateTextGenerationOptions(options) {
241
+ const errors = [];
242
+ const warnings = [];
243
+ const suggestions = [];
244
+ if (!isNonNullObject(options)) {
245
+ errors.push(new ValidationError("Options must be an object", "options", "INVALID_TYPE"));
246
+ return { isValid: false, errors, warnings, suggestions };
247
+ }
248
+ const opts = options;
249
+ // Validate prompt
250
+ const promptError = validateRequiredString(opts.prompt, "prompt", 1);
251
+ if (promptError) {
252
+ errors.push(promptError);
253
+ }
254
+ if (opts.prompt && opts.prompt.length > SYSTEM_LIMITS.MAX_PROMPT_LENGTH) {
255
+ errors.push(new ValidationError(`Prompt too large: ${opts.prompt.length} characters (max: ${SYSTEM_LIMITS.MAX_PROMPT_LENGTH})`, "prompt", "MAX_LENGTH", [
256
+ "Break prompt into smaller chunks",
257
+ "Use summarization for long content",
258
+ "Consider using streaming for large inputs",
259
+ ]));
260
+ }
261
+ // Validate temperature
262
+ const tempError = validateNumberRange(opts.temperature, "temperature", 0, 2);
263
+ if (tempError) {
264
+ errors.push(tempError);
265
+ }
266
+ // Validate maxTokens
267
+ const tokensError = validateNumberRange(opts.maxTokens, "maxTokens", 1, 200000);
268
+ if (tokensError) {
269
+ errors.push(tokensError);
270
+ }
271
+ // Validate timeout
272
+ if (opts.timeout !== undefined) {
273
+ if (typeof opts.timeout === "string") {
274
+ // Parse string timeouts like "30s", "2m", "1h"
275
+ if (!/^\d+[smh]?$/.test(opts.timeout)) {
276
+ errors.push(new ValidationError("Invalid timeout format. Use number (ms) or string like '30s', '2m', '1h'", "timeout", "INVALID_FORMAT", ["Use format: 30000 (ms), '30s', '2m', or '1h'"]));
277
+ }
278
+ }
279
+ else if (typeof opts.timeout === "number") {
280
+ if (opts.timeout < 1000 || opts.timeout > 600000) {
281
+ warnings.push("Timeout outside recommended range (1s - 10m)");
282
+ suggestions.push("Use timeout between 1000ms (1s) and 600000ms (10m)");
283
+ }
284
+ }
285
+ else {
286
+ errors.push(new ValidationError("Timeout must be a number (ms) or string", "timeout", "INVALID_TYPE"));
287
+ }
288
+ }
289
+ return { isValid: errors.length === 0, errors, warnings, suggestions };
290
+ }
291
+ /**
292
+ * Validate stream options
293
+ */
294
+ export function validateStreamOptions(options) {
295
+ const errors = [];
296
+ const warnings = [];
297
+ const suggestions = [];
298
+ if (!isNonNullObject(options)) {
299
+ errors.push(new ValidationError("Options must be an object", "options", "INVALID_TYPE"));
300
+ return { isValid: false, errors, warnings, suggestions };
301
+ }
302
+ const opts = options;
303
+ // Validate input
304
+ if (!opts.input || !isNonNullObject(opts.input)) {
305
+ errors.push(new ValidationError("input is required and must be an object with text property", "input", "REQUIRED_FIELD", ["Provide input: { text: 'your prompt here' }"]));
306
+ }
307
+ else {
308
+ const inputError = validateRequiredString(opts.input.text, "input.text", 1);
309
+ if (inputError) {
310
+ errors.push(inputError);
311
+ }
312
+ }
313
+ // Validate temperature
314
+ const tempError = validateNumberRange(opts.temperature, "temperature", 0, 2);
315
+ if (tempError) {
316
+ errors.push(tempError);
317
+ }
318
+ // Validate maxTokens
319
+ const tokensError = validateNumberRange(opts.maxTokens, "maxTokens", 1, 200000);
320
+ if (tokensError) {
321
+ errors.push(tokensError);
322
+ }
323
+ return { isValid: errors.length === 0, errors, warnings, suggestions };
324
+ }
325
+ /**
326
+ * Validate generate options (unified interface)
327
+ */
328
+ export function validateGenerateOptions(options) {
329
+ const errors = [];
330
+ const warnings = [];
331
+ const suggestions = [];
332
+ if (!isNonNullObject(options)) {
333
+ errors.push(new ValidationError("Options must be an object", "options", "INVALID_TYPE"));
334
+ return { isValid: false, errors, warnings, suggestions };
335
+ }
336
+ const opts = options;
337
+ // Validate input
338
+ if (!opts.input || !isNonNullObject(opts.input)) {
339
+ errors.push(new ValidationError("input is required and must be an object with text property", "input", "REQUIRED_FIELD", ["Provide input: { text: 'your prompt here' }"]));
340
+ }
341
+ else {
342
+ const inputError = validateRequiredString(opts.input.text, "input.text", 1);
343
+ if (inputError) {
344
+ errors.push(inputError);
345
+ }
346
+ }
347
+ // Common validation for temperature and maxTokens
348
+ const tempError = validateNumberRange(opts.temperature, "temperature", 0, 2);
349
+ if (tempError) {
350
+ errors.push(tempError);
351
+ }
352
+ const tokensError = validateNumberRange(opts.maxTokens, "maxTokens", 1, 200000);
353
+ if (tokensError) {
354
+ errors.push(tokensError);
355
+ }
356
+ // Validate factory config if present
357
+ if (opts.factoryConfig && !isNonNullObject(opts.factoryConfig)) {
358
+ warnings.push("factoryConfig should be an object if provided");
359
+ suggestions.push("Provide valid factory configuration or remove the property");
360
+ }
361
+ return { isValid: errors.length === 0, errors, warnings, suggestions };
362
+ }
363
+ // ============================================================================
364
+ // PARAMETER TRANSFORMATION VALIDATORS
365
+ // ============================================================================
366
+ /**
367
+ * Validate tool execution parameters
368
+ */
369
+ export function validateToolExecutionParams(toolName, params, expectedSchema) {
370
+ const errors = [];
371
+ const warnings = [];
372
+ const suggestions = [];
373
+ // Basic parameter validation
374
+ if (params !== undefined && params !== null && !isNonNullObject(params)) {
375
+ errors.push(new ValidationError(`Parameters for tool '${toolName}' must be an object`, "params", "INVALID_TYPE", ["Provide parameters as an object: { key: value, ... }"]));
376
+ return { isValid: false, errors, warnings, suggestions };
377
+ }
378
+ // Schema validation (if provided)
379
+ if (expectedSchema && params) {
380
+ try {
381
+ // This is a placeholder for actual schema validation
382
+ // In practice, you would use Zod or JSON schema validation here
383
+ warnings.push("Schema validation not yet implemented");
384
+ suggestions.push("Implement Zod schema validation for tool parameters");
385
+ }
386
+ catch (error) {
387
+ errors.push(new ValidationError(`Parameter validation failed: ${error instanceof Error ? error.message : String(error)}`, "params", "SCHEMA_VALIDATION", ["Check parameter format against tool schema"]));
388
+ }
389
+ }
390
+ return { isValid: errors.length === 0, errors, warnings, suggestions };
391
+ }
392
+ // ============================================================================
393
+ // BATCH VALIDATION UTILITIES
394
+ // ============================================================================
395
+ /**
396
+ * Validate multiple tools at once
397
+ */
398
+ export function validateToolBatch(tools) {
399
+ const validTools = [];
400
+ const invalidTools = [];
401
+ const results = {};
402
+ for (const [name, tool] of Object.entries(tools)) {
403
+ const nameValidation = validateToolName(name);
404
+ const toolValidation = validateMCPTool(tool);
405
+ const combinedResult = {
406
+ isValid: !nameValidation && toolValidation.isValid,
407
+ errors: nameValidation
408
+ ? [nameValidation, ...toolValidation.errors]
409
+ : toolValidation.errors,
410
+ warnings: toolValidation.warnings,
411
+ suggestions: toolValidation.suggestions,
412
+ };
413
+ results[name] = combinedResult;
414
+ if (combinedResult.isValid) {
415
+ validTools.push(name);
416
+ }
417
+ else {
418
+ invalidTools.push(name);
419
+ }
420
+ }
421
+ return {
422
+ isValid: invalidTools.length === 0,
423
+ validTools,
424
+ invalidTools,
425
+ results,
426
+ };
427
+ }
428
+ // ============================================================================
429
+ // HELPER FUNCTIONS
430
+ // ============================================================================
431
+ /**
432
+ * Create a validation error summary for logging
433
+ */
434
+ export function createValidationSummary(result) {
435
+ const parts = [];
436
+ if (result.errors.length > 0) {
437
+ parts.push(`Errors: ${result.errors.map((e) => e.message).join("; ")}`);
438
+ }
439
+ if (result.warnings.length > 0) {
440
+ parts.push(`Warnings: ${result.warnings.join("; ")}`);
441
+ }
442
+ if (result.suggestions.length > 0) {
443
+ parts.push(`Suggestions: ${result.suggestions.join("; ")}`);
444
+ }
445
+ return parts.join(" | ");
446
+ }
447
+ /**
448
+ * Check if validation result has only warnings (no errors)
449
+ */
450
+ export function hasOnlyWarnings(result) {
451
+ return result.errors.length === 0 && result.warnings.length > 0;
452
+ }
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Object Transformation Utilities
3
+ * Centralizes repeated object transformation patterns to improve code reuse and maintainability
4
+ */
5
+ import type { StandardRecord, StringArray } from "../types/typeAliases.js";
6
+ /**
7
+ * Transform tool execution results from AI SDK format to NeuroLink GenerateResult format
8
+ * Handles both single execution and array formats with robust type checking
9
+ *
10
+ * @param toolExecutions - Array of tool execution results from AI SDK (optional)
11
+ * @returns Array of standardized tool execution objects with name, input, output, and duration
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const executions = transformToolExecutions([
16
+ * { name: "calculator", input: { a: 5, b: 3 }, output: 8, duration: 150 }
17
+ * ]);
18
+ * // Returns: [{ name: "calculator", input: { a: 5, b: 3 }, output: 8, duration: 150 }]
19
+ * ```
20
+ */
21
+ export declare function transformToolExecutions(toolExecutions?: unknown[]): Array<{
22
+ name: string;
23
+ input: StandardRecord;
24
+ output: unknown;
25
+ duration: number;
26
+ }>;
27
+ /**
28
+ * Transform tool execution results from AI SDK format to internal format (for MCP generation)
29
+ * Used in tryMCPGeneration method
30
+ */
31
+ export declare function transformToolExecutionsForMCP(toolExecutions?: unknown[]): Array<{
32
+ toolName: string;
33
+ executionTime: number;
34
+ success: boolean;
35
+ serverId?: string;
36
+ }>;
37
+ /**
38
+ * Transform available tools from internal format to GenerateResult format
39
+ * Ensures consistent tool information structure across the API with schema normalization
40
+ *
41
+ * @param availableTools - Array of tool definitions from various sources (MCP servers, builtin tools, etc.)
42
+ * @returns Array of normalized tool descriptions with consistent schema format
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const tools = transformAvailableTools([
47
+ * { name: "calculator", description: "Math tool", server: "builtin", inputSchema: {...} }
48
+ * ]);
49
+ * // Returns: [{ name: "calculator", description: "Math tool", serverId: "builtin", schema: {...} }]
50
+ * ```
51
+ */
52
+ export declare function transformAvailableTools(availableTools?: Array<{
53
+ name: string;
54
+ description: string;
55
+ server: string;
56
+ category?: string;
57
+ inputSchema?: StandardRecord;
58
+ parameters?: StandardRecord;
59
+ schema?: StandardRecord;
60
+ }>): Array<{
61
+ name: string;
62
+ description: string;
63
+ server: string;
64
+ parameters: StandardRecord;
65
+ }>;
66
+ /**
67
+ * Transform tools for MCP generation format
68
+ * Simple transformation for internal MCP tool lists
69
+ */
70
+ export declare function transformToolsForMCP(availableTools: Array<{
71
+ name: string;
72
+ description: string;
73
+ server: string;
74
+ category?: string;
75
+ }>): Array<{
76
+ name: string;
77
+ description: string;
78
+ server: string;
79
+ category?: string;
80
+ }>;
81
+ /**
82
+ * Transform tools to expected format with required properties
83
+ * Used in getAllAvailableTools method for final output
84
+ */
85
+ export declare function transformToolsToExpectedFormat(tools: Array<{
86
+ name: string;
87
+ description?: string;
88
+ serverId?: string;
89
+ category?: string;
90
+ inputSchema?: StandardRecord;
91
+ }>): Array<{
92
+ name: string;
93
+ description: string;
94
+ server: string;
95
+ category?: string;
96
+ inputSchema?: StandardRecord;
97
+ }>;
98
+ /**
99
+ * Extract tool names from tool objects
100
+ * Common pattern for creating arrays of tool names
101
+ */
102
+ export declare function extractToolNames<T extends {
103
+ name: string;
104
+ }>(tools: T[]): StringArray;
105
+ /**
106
+ * Extract object keys as a comma-separated string
107
+ * Common pattern for logging and debugging
108
+ */
109
+ export declare function getKeysAsString(obj: StandardRecord, fallback?: string): string;
110
+ /**
111
+ * Count object properties
112
+ * Common pattern for metrics and logging
113
+ */
114
+ export declare function getKeyCount(obj: StandardRecord): number;
115
+ /**
116
+ * Transform schema properties to parameter descriptions
117
+ * Used in tool-aware system prompt generation
118
+ */
119
+ export declare function transformSchemaToParameterDescription(schema: {
120
+ properties?: StandardRecord;
121
+ required?: string[];
122
+ }): string;
123
+ /**
124
+ * Transform tools to tool descriptions for system prompts
125
+ * Consolidated pattern for creating tool-aware prompts
126
+ */
127
+ export declare function transformToolsToDescriptions(availableTools: Array<{
128
+ name: string;
129
+ description: string;
130
+ server: string;
131
+ inputSchema?: StandardRecord;
132
+ }>): string;
133
+ /**
134
+ * Transform parameters for validation
135
+ * Common pattern when logging or checking parameter structures
136
+ */
137
+ export declare function transformParamsForLogging(params: unknown): string;
138
+ /**
139
+ * Safe property extraction from unknown objects
140
+ * Common pattern for safely accessing properties from unknown structures
141
+ */
142
+ export declare function safeExtractProperty<T = unknown>(obj: unknown, key: string, fallback: T): T;
143
+ /**
144
+ * Safe extraction of string properties
145
+ * Specialized version for string properties with fallback
146
+ */
147
+ export declare function safeExtractString(obj: unknown, key: string, fallback?: string): string;
148
+ /**
149
+ * Safe extraction of number properties
150
+ * Specialized version for number properties with fallback
151
+ */
152
+ export declare function safeExtractNumber(obj: unknown, key: string, fallback?: number): number;
153
+ /**
154
+ * Safe extraction of boolean properties
155
+ * Specialized version for boolean properties with fallback
156
+ */
157
+ export declare function safeExtractBoolean(obj: unknown, key: string, fallback?: boolean): boolean;
158
+ /**
159
+ * Transform Map to array of values
160
+ * Common pattern for converting tool maps to arrays
161
+ */
162
+ export declare function mapToArray<T>(map: Map<string, T>): T[];
163
+ /**
164
+ * Transform Map to array of key-value pairs
165
+ * Common pattern for processing map entries
166
+ */
167
+ export declare function mapToEntries<T>(map: Map<string, T>): Array<[string, T]>;
168
+ /**
169
+ * Group array items by a key
170
+ * Common pattern for organizing tools or other objects by category
171
+ */
172
+ export declare function groupBy<T>(items: T[], keyFn: (item: T) => string): Map<string, T[]>;
173
+ /**
174
+ * Remove undefined properties from objects
175
+ * Common pattern for cleaning up object structures
176
+ */
177
+ export declare function removeUndefinedProperties<T extends StandardRecord>(obj: T): T;
178
+ /**
179
+ * Merge objects with undefined handling
180
+ * Common pattern for combining configuration objects
181
+ */
182
+ export declare function mergeWithUndefinedHandling<T extends StandardRecord>(target: T, ...sources: Partial<T>[]): T;
183
+ /**
184
+ * Optimize tool information for collection with minimal object creation
185
+ * Consolidates repeated optimization patterns across different tool sources
186
+ *
187
+ * @param tool - Tool information to optimize
188
+ * @param defaults - Default values to apply if missing
189
+ * @returns Optimized tool with minimal object creation
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const optimized = optimizeToolForCollection(tool, {
194
+ * serverId: "builtin",
195
+ * category: "math"
196
+ * });
197
+ * ```
198
+ */
199
+ export declare function optimizeToolForCollection<T extends Record<string, unknown>>(tool: T, defaults: {
200
+ description?: string;
201
+ serverId?: string;
202
+ category?: string;
203
+ inputSchema?: StandardRecord;
204
+ }): T;