@juspay/neurolink 7.6.1 → 7.7.1

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 (138) hide show
  1. package/CHANGELOG.md +15 -4
  2. package/README.md +78 -3
  3. package/dist/cli/commands/config.d.ts +275 -3
  4. package/dist/cli/commands/config.js +121 -0
  5. package/dist/cli/commands/mcp.js +77 -28
  6. package/dist/cli/factories/commandFactory.js +359 -6
  7. package/dist/core/analytics.js +7 -27
  8. package/dist/core/baseProvider.js +43 -4
  9. package/dist/core/constants.d.ts +46 -0
  10. package/dist/core/constants.js +47 -0
  11. package/dist/core/dynamicModels.d.ts +16 -4
  12. package/dist/core/dynamicModels.js +130 -26
  13. package/dist/core/evaluation.js +5 -1
  14. package/dist/core/evaluationProviders.d.ts +6 -2
  15. package/dist/core/evaluationProviders.js +41 -125
  16. package/dist/core/factory.d.ts +5 -0
  17. package/dist/core/factory.js +62 -50
  18. package/dist/core/modelConfiguration.d.ts +246 -0
  19. package/dist/core/modelConfiguration.js +775 -0
  20. package/dist/core/types.d.ts +22 -3
  21. package/dist/core/types.js +5 -1
  22. package/dist/factories/providerRegistry.js +3 -3
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/lib/core/analytics.js +7 -27
  26. package/dist/lib/core/baseProvider.js +43 -4
  27. package/dist/lib/core/constants.d.ts +46 -0
  28. package/dist/lib/core/constants.js +47 -0
  29. package/dist/lib/core/dynamicModels.d.ts +16 -4
  30. package/dist/lib/core/dynamicModels.js +130 -26
  31. package/dist/lib/core/evaluation.js +5 -1
  32. package/dist/lib/core/evaluationProviders.d.ts +6 -2
  33. package/dist/lib/core/evaluationProviders.js +41 -125
  34. package/dist/lib/core/factory.d.ts +5 -0
  35. package/dist/lib/core/factory.js +63 -50
  36. package/dist/lib/core/modelConfiguration.d.ts +246 -0
  37. package/dist/lib/core/modelConfiguration.js +775 -0
  38. package/dist/lib/core/types.d.ts +22 -3
  39. package/dist/lib/core/types.js +5 -1
  40. package/dist/lib/factories/providerRegistry.js +3 -3
  41. package/dist/lib/index.d.ts +1 -1
  42. package/dist/lib/index.js +1 -1
  43. package/dist/lib/mcp/factory.d.ts +5 -5
  44. package/dist/lib/mcp/factory.js +2 -2
  45. package/dist/lib/mcp/servers/utilities/utilityServer.d.ts +1 -1
  46. package/dist/lib/mcp/servers/utilities/utilityServer.js +1 -1
  47. package/dist/lib/mcp/toolRegistry.js +2 -2
  48. package/dist/lib/neurolink.d.ts +168 -12
  49. package/dist/lib/neurolink.js +685 -123
  50. package/dist/lib/providers/anthropic.js +52 -2
  51. package/dist/lib/providers/googleAiStudio.js +4 -0
  52. package/dist/lib/providers/googleVertex.d.ts +75 -9
  53. package/dist/lib/providers/googleVertex.js +365 -46
  54. package/dist/lib/providers/huggingFace.d.ts +52 -11
  55. package/dist/lib/providers/huggingFace.js +180 -42
  56. package/dist/lib/providers/litellm.d.ts +9 -9
  57. package/dist/lib/providers/litellm.js +103 -16
  58. package/dist/lib/providers/ollama.d.ts +52 -17
  59. package/dist/lib/providers/ollama.js +276 -68
  60. package/dist/lib/sdk/toolRegistration.d.ts +42 -0
  61. package/dist/lib/sdk/toolRegistration.js +269 -27
  62. package/dist/lib/telemetry/telemetryService.d.ts +6 -0
  63. package/dist/lib/telemetry/telemetryService.js +38 -3
  64. package/dist/lib/types/contextTypes.d.ts +75 -11
  65. package/dist/lib/types/contextTypes.js +227 -1
  66. package/dist/lib/types/domainTypes.d.ts +62 -0
  67. package/dist/lib/types/domainTypes.js +5 -0
  68. package/dist/lib/types/generateTypes.d.ts +52 -0
  69. package/dist/lib/types/index.d.ts +1 -0
  70. package/dist/lib/types/mcpTypes.d.ts +1 -1
  71. package/dist/lib/types/mcpTypes.js +1 -1
  72. package/dist/lib/types/streamTypes.d.ts +14 -0
  73. package/dist/lib/types/universalProviderOptions.d.ts +1 -1
  74. package/dist/lib/utils/errorHandling.d.ts +142 -0
  75. package/dist/lib/utils/errorHandling.js +316 -0
  76. package/dist/lib/utils/factoryProcessing.d.ts +74 -0
  77. package/dist/lib/utils/factoryProcessing.js +588 -0
  78. package/dist/lib/utils/optionsConversion.d.ts +54 -0
  79. package/dist/lib/utils/optionsConversion.js +126 -0
  80. package/dist/lib/utils/optionsUtils.d.ts +246 -0
  81. package/dist/lib/utils/optionsUtils.js +960 -0
  82. package/dist/lib/utils/providerConfig.js +6 -2
  83. package/dist/lib/utils/providerHealth.d.ts +107 -0
  84. package/dist/lib/utils/providerHealth.js +543 -0
  85. package/dist/lib/utils/providerUtils.d.ts +17 -0
  86. package/dist/lib/utils/providerUtils.js +271 -16
  87. package/dist/lib/utils/timeout.js +1 -1
  88. package/dist/lib/utils/tokenLimits.d.ts +33 -0
  89. package/dist/lib/utils/tokenLimits.js +118 -0
  90. package/dist/mcp/factory.d.ts +5 -5
  91. package/dist/mcp/factory.js +2 -2
  92. package/dist/mcp/servers/utilities/utilityServer.d.ts +1 -1
  93. package/dist/mcp/servers/utilities/utilityServer.js +1 -1
  94. package/dist/mcp/toolRegistry.js +2 -2
  95. package/dist/neurolink.d.ts +168 -12
  96. package/dist/neurolink.js +685 -123
  97. package/dist/providers/anthropic.js +52 -2
  98. package/dist/providers/googleAiStudio.js +4 -0
  99. package/dist/providers/googleVertex.d.ts +75 -9
  100. package/dist/providers/googleVertex.js +365 -46
  101. package/dist/providers/huggingFace.d.ts +52 -11
  102. package/dist/providers/huggingFace.js +181 -43
  103. package/dist/providers/litellm.d.ts +9 -9
  104. package/dist/providers/litellm.js +103 -16
  105. package/dist/providers/ollama.d.ts +52 -17
  106. package/dist/providers/ollama.js +276 -68
  107. package/dist/sdk/toolRegistration.d.ts +42 -0
  108. package/dist/sdk/toolRegistration.js +269 -27
  109. package/dist/telemetry/telemetryService.d.ts +6 -0
  110. package/dist/telemetry/telemetryService.js +38 -3
  111. package/dist/types/contextTypes.d.ts +75 -11
  112. package/dist/types/contextTypes.js +227 -2
  113. package/dist/types/domainTypes.d.ts +62 -0
  114. package/dist/types/domainTypes.js +5 -0
  115. package/dist/types/generateTypes.d.ts +52 -0
  116. package/dist/types/index.d.ts +1 -0
  117. package/dist/types/mcpTypes.d.ts +1 -1
  118. package/dist/types/mcpTypes.js +1 -1
  119. package/dist/types/streamTypes.d.ts +14 -0
  120. package/dist/types/universalProviderOptions.d.ts +1 -1
  121. package/dist/types/universalProviderOptions.js +0 -1
  122. package/dist/utils/errorHandling.d.ts +142 -0
  123. package/dist/utils/errorHandling.js +316 -0
  124. package/dist/utils/factoryProcessing.d.ts +74 -0
  125. package/dist/utils/factoryProcessing.js +588 -0
  126. package/dist/utils/optionsConversion.d.ts +54 -0
  127. package/dist/utils/optionsConversion.js +126 -0
  128. package/dist/utils/optionsUtils.d.ts +246 -0
  129. package/dist/utils/optionsUtils.js +960 -0
  130. package/dist/utils/providerConfig.js +6 -2
  131. package/dist/utils/providerHealth.d.ts +107 -0
  132. package/dist/utils/providerHealth.js +543 -0
  133. package/dist/utils/providerUtils.d.ts +17 -0
  134. package/dist/utils/providerUtils.js +271 -16
  135. package/dist/utils/timeout.js +1 -1
  136. package/dist/utils/tokenLimits.d.ts +33 -0
  137. package/dist/utils/tokenLimits.js +118 -0
  138. package/package.json +2 -2
@@ -11,6 +11,56 @@ import { logger } from "../utils/logger.js";
11
11
  */
12
12
  const envValue = parseInt(process.env.NEUROLINK_TOOL_DESCRIPTION_MAX_LENGTH || "200", 10);
13
13
  const DEFAULT_DESCRIPTION_MAX_LENGTH = Number.isInteger(envValue) && envValue > 0 ? envValue : 200;
14
+ /**
15
+ * Enhanced validation configuration
16
+ */
17
+ const VALIDATION_CONFIG = {
18
+ // Tool name constraints
19
+ NAME_MIN_LENGTH: 2,
20
+ NAME_MAX_LENGTH: 50,
21
+ // Description constraints
22
+ DESCRIPTION_MIN_LENGTH: 10,
23
+ DESCRIPTION_MAX_LENGTH: DEFAULT_DESCRIPTION_MAX_LENGTH,
24
+ // Reserved tool names that cannot be used
25
+ RESERVED_NAMES: new Set([
26
+ "system",
27
+ "internal",
28
+ "core",
29
+ "ai",
30
+ "assistant",
31
+ "help",
32
+ "debug",
33
+ "test",
34
+ "mock",
35
+ "default",
36
+ "config",
37
+ "admin",
38
+ "root",
39
+ "neurolink",
40
+ ]),
41
+ // Recommended tool name patterns
42
+ RECOMMENDED_PATTERNS: [
43
+ "get_data",
44
+ "fetch_info",
45
+ "calculate_value",
46
+ "send_message",
47
+ "create_item",
48
+ "update_record",
49
+ "delete_file",
50
+ "validate_input",
51
+ ],
52
+ // Pre-compiled regex patterns for performance optimization
53
+ COMPILED_PATTERN_REGEXES: [
54
+ "get_data",
55
+ "fetch_info",
56
+ "calculate_value",
57
+ "send_message",
58
+ "create_item",
59
+ "update_record",
60
+ "delete_file",
61
+ "validate_input",
62
+ ].map((pattern) => new RegExp(pattern.replace(/_/g, "[_-]"), "i")),
63
+ };
14
64
  /**
15
65
  * Converts a SimpleTool to Vercel AI SDK format
16
66
  */
@@ -89,50 +139,147 @@ export function createTool(config) {
89
139
  return config;
90
140
  }
91
141
  /**
92
- * Helper to create a tool with typed parameters
142
+ * Helper to create a validated tool with suggested improvements
93
143
  */
94
- export function createTypedTool(config) {
95
- return config;
144
+ export function createValidatedTool(name, config, options = {}) {
145
+ const { strict = true, suggestions = true } = options;
146
+ try {
147
+ // Validate the tool
148
+ validateTool(name, config);
149
+ // Provide helpful suggestions if enabled
150
+ if (suggestions) {
151
+ provideToolSuggestions(name, config);
152
+ }
153
+ logger.debug(`Tool '${name}' created and validated successfully`);
154
+ return config;
155
+ }
156
+ catch (error) {
157
+ if (strict) {
158
+ throw error;
159
+ }
160
+ // Log warning but continue in non-strict mode
161
+ logger.warn(`Tool '${name}' validation failed in non-strict mode`, {
162
+ error: error instanceof Error ? error.message : String(error),
163
+ });
164
+ return config;
165
+ }
96
166
  }
97
167
  /**
98
- * Validate tool description length
168
+ * Provide helpful suggestions for tool improvement
99
169
  */
100
- function validateDescriptionLength(name, description) {
101
- const maxDescriptionLength = Number.isInteger(DEFAULT_DESCRIPTION_MAX_LENGTH) &&
102
- DEFAULT_DESCRIPTION_MAX_LENGTH > 0
103
- ? DEFAULT_DESCRIPTION_MAX_LENGTH
104
- : 200;
105
- if (description.length > maxDescriptionLength) {
106
- throw new Error(`Tool '${name}' description should be concise (max ${maxDescriptionLength} characters). ` +
107
- `Current length: ${description.length}. ` +
108
- `Consider shortening: "${description.substring(0, 50)}..."`);
170
+ function provideToolSuggestions(name, tool) {
171
+ const suggestions = [];
172
+ // Check for common improvements
173
+ if (!tool.parameters) {
174
+ suggestions.push("Consider adding a parameters schema using Zod for better type safety and validation");
175
+ }
176
+ if (!tool.metadata?.category) {
177
+ suggestions.push("Adding a category in metadata helps organize tools: { metadata: { category: 'data' } }");
178
+ }
179
+ if (!tool.metadata?.version) {
180
+ suggestions.push("Adding a version helps track tool updates: { metadata: { version: '1.0.0' } }");
181
+ }
182
+ // Check description quality
183
+ const description = tool.description.toLowerCase();
184
+ if (!description.includes("return") && !description.includes("result")) {
185
+ suggestions.push("Consider describing what the tool returns for better AI understanding");
186
+ }
187
+ if (suggestions.length > 0) {
188
+ logger.debug(`Tool '${name}' suggestions for improvement:`, {
189
+ suggestions: suggestions.slice(0, 3), // Limit to avoid spam
190
+ });
109
191
  }
110
192
  }
111
193
  /**
112
- * Validate tool configuration with detailed error messages
194
+ * Helper to create a tool with typed parameters
113
195
  */
114
- export function validateTool(name, tool) {
115
- // Validate tool name
196
+ export function createTypedTool(config) {
197
+ return config;
198
+ }
199
+ /**
200
+ * Enhanced tool name validation
201
+ */
202
+ function validateToolName(name) {
203
+ // Basic validation
116
204
  if (!name || typeof name !== "string" || name.trim() === "") {
117
205
  throw new Error(`Invalid tool name: must be a non-empty string. Received: ${name}`);
118
206
  }
119
- // Validate tool name format (alphanumeric, hyphens, underscores only)
207
+ const trimmedName = name.trim();
208
+ // Length validation
209
+ if (trimmedName.length < VALIDATION_CONFIG.NAME_MIN_LENGTH) {
210
+ throw new Error(`Tool name too short: '${name}' (${trimmedName.length} chars). ` +
211
+ `Minimum length: ${VALIDATION_CONFIG.NAME_MIN_LENGTH} characters. ` +
212
+ `Example: 'get_data', 'send_email'`);
213
+ }
214
+ if (trimmedName.length > VALIDATION_CONFIG.NAME_MAX_LENGTH) {
215
+ throw new Error(`Tool name too long: '${name}' (${trimmedName.length} chars). ` +
216
+ `Maximum length: ${VALIDATION_CONFIG.NAME_MAX_LENGTH} characters. ` +
217
+ `Consider shortening: '${trimmedName.substring(0, 20)}...'`);
218
+ }
219
+ // Format validation (alphanumeric, hyphens, underscores only)
120
220
  const validNamePattern = /^[a-zA-Z0-9_-]+$/;
121
- if (!validNamePattern.test(name)) {
221
+ if (!validNamePattern.test(trimmedName)) {
122
222
  throw new Error(`Invalid tool name format: '${name}'. Tool names must contain only alphanumeric characters, hyphens, and underscores. ` +
123
223
  `Examples: 'calculate-tax', 'get_weather', 'sendEmail123'`);
124
224
  }
125
- // Validate tool object
126
- if (!tool || typeof tool !== "object") {
127
- throw new Error(`Tool '${name}' must be an object with description and execute properties. Received: ${typeof tool}`);
225
+ // Reserved name validation
226
+ if (VALIDATION_CONFIG.RESERVED_NAMES.has(trimmedName.toLowerCase())) {
227
+ throw new Error(`Tool name '${name}' is reserved and cannot be used. ` +
228
+ `Reserved names include: ${Array.from(VALIDATION_CONFIG.RESERVED_NAMES).slice(0, 5).join(", ")}... ` +
229
+ `Try variations like: '${trimmedName}_tool', 'custom_${trimmedName}', '${trimmedName}_helper'`);
230
+ }
231
+ // Naming convention suggestions using pre-compiled patterns for performance
232
+ const hasGoodPattern = VALIDATION_CONFIG.COMPILED_PATTERN_REGEXES.some((patternRegex) => {
233
+ return patternRegex.test(trimmedName);
234
+ });
235
+ if (!hasGoodPattern && trimmedName.length > 10) {
236
+ logger.debug(`Tool name '${name}' could follow recommended patterns for better clarity. ` +
237
+ `Consider patterns like: ${VALIDATION_CONFIG.RECOMMENDED_PATTERNS.slice(0, 4).join(", ")}`);
128
238
  }
129
- // Validate description
130
- if (!tool.description ||
131
- typeof tool.description !== "string" ||
132
- tool.description.trim() === "") {
239
+ }
240
+ /**
241
+ * Enhanced description validation
242
+ */
243
+ function validateToolDescription(name, description) {
244
+ if (!description ||
245
+ typeof description !== "string" ||
246
+ description.trim() === "") {
133
247
  throw new Error(`Tool '${name}' must have a non-empty description string. ` +
134
248
  `Example: { description: "Calculates mathematical expressions", execute: async (params) => {...} }`);
135
249
  }
250
+ const trimmedDescription = description.trim();
251
+ // Length validation
252
+ if (trimmedDescription.length < VALIDATION_CONFIG.DESCRIPTION_MIN_LENGTH) {
253
+ throw new Error(`Tool '${name}' description too short: ${trimmedDescription.length} characters. ` +
254
+ `Minimum length: ${VALIDATION_CONFIG.DESCRIPTION_MIN_LENGTH} characters. ` +
255
+ `The description should clearly explain what the tool does and when to use it. ` +
256
+ `Example: "Fetches current weather data for a specified location using coordinates or city name"`);
257
+ }
258
+ if (trimmedDescription.length > VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH) {
259
+ throw new Error(`Tool '${name}' description too long: ${trimmedDescription.length} characters. ` +
260
+ `Maximum length: ${VALIDATION_CONFIG.DESCRIPTION_MAX_LENGTH} characters. ` +
261
+ `Current description: "${trimmedDescription.substring(0, 50)}..." ` +
262
+ `Try to be more concise while keeping the essential information.`);
263
+ }
264
+ // Quality suggestions
265
+ const hasActionWord = /^(get|fetch|calculate|send|create|update|delete|validate|process|generate|parse|convert)/i.test(trimmedDescription);
266
+ if (!hasActionWord) {
267
+ logger.debug(`Tool '${name}' description could start with an action word (get, fetch, calculate, etc.) for better clarity: "${trimmedDescription.substring(0, 30)}..."`);
268
+ }
269
+ }
270
+ /**
271
+ * Validate tool configuration with detailed error messages
272
+ */
273
+ export function validateTool(name, tool) {
274
+ // Enhanced tool name validation
275
+ validateToolName(name);
276
+ // Validate tool object
277
+ if (!tool || typeof tool !== "object") {
278
+ throw new Error(`Tool '${name}' must be an object with description and execute properties. Received: ${typeof tool}. ` +
279
+ `Expected format: { description: "Tool description", execute: async (params) => { ... } }`);
280
+ }
281
+ // Enhanced description validation
282
+ validateToolDescription(name, tool.description);
136
283
  // Validate execute function with signature guidance
137
284
  if (typeof tool.execute !== "function") {
138
285
  throw new Error(`Tool '${name}' must have an execute function. ` +
@@ -181,6 +328,101 @@ export function validateTool(name, tool) {
181
328
  throw new Error(errorMessage);
182
329
  }
183
330
  }
184
- // Validate description length for better UX
185
- validateDescriptionLength(name, tool.description);
331
+ // Validate metadata if provided
332
+ if (tool.metadata) {
333
+ if (typeof tool.metadata !== "object" || Array.isArray(tool.metadata)) {
334
+ throw new Error(`Tool '${name}' metadata must be an object. Received: ${typeof tool.metadata}. ` +
335
+ `Example: { category: "data", version: "1.0.0", author: "team@company.com" }`);
336
+ }
337
+ // Validate metadata fields
338
+ if (tool.metadata.version && typeof tool.metadata.version !== "string") {
339
+ throw new Error(`Tool '${name}' metadata.version must be a string. Received: ${typeof tool.metadata.version}. ` +
340
+ `Example: "1.0.0", "2.1.3-beta"`);
341
+ }
342
+ if (tool.metadata.category && typeof tool.metadata.category !== "string") {
343
+ throw new Error(`Tool '${name}' metadata.category must be a string. Received: ${typeof tool.metadata.category}. ` +
344
+ `Example: "data", "communication", "utility"`);
345
+ }
346
+ if (tool.metadata.tags && !Array.isArray(tool.metadata.tags)) {
347
+ throw new Error(`Tool '${name}' metadata.tags must be an array of strings. Received: ${typeof tool.metadata.tags}. ` +
348
+ `Example: ["api", "external", "web"]`);
349
+ }
350
+ }
351
+ // Success feedback for debugging
352
+ logger.debug(`Tool '${name}' validation passed`, {
353
+ nameLength: name.length,
354
+ descriptionLength: tool.description.length,
355
+ hasParameters: !!tool.parameters,
356
+ hasMetadata: !!tool.metadata,
357
+ });
358
+ }
359
+ /**
360
+ * Utility to validate multiple tools at once
361
+ */
362
+ export function validateTools(tools) {
363
+ const valid = [];
364
+ const invalid = [];
365
+ for (const [name, tool] of Object.entries(tools)) {
366
+ try {
367
+ validateTool(name, tool);
368
+ valid.push(name);
369
+ }
370
+ catch (error) {
371
+ invalid.push({
372
+ name,
373
+ error: error instanceof Error ? error.message : String(error),
374
+ });
375
+ }
376
+ }
377
+ logger.debug(`Bulk validation completed`, {
378
+ validCount: valid.length,
379
+ invalidCount: invalid.length,
380
+ totalTools: Object.keys(tools).length,
381
+ });
382
+ return { valid, invalid };
383
+ }
384
+ /**
385
+ * Get validation configuration for external inspection
386
+ */
387
+ export function getValidationConfig() {
388
+ return { ...VALIDATION_CONFIG };
389
+ }
390
+ /**
391
+ * Check if a tool name is available (not reserved)
392
+ */
393
+ export function isToolNameAvailable(name) {
394
+ if (!name || typeof name !== "string") {
395
+ return false;
396
+ }
397
+ const trimmedName = name.trim().toLowerCase();
398
+ return (trimmedName.length >= VALIDATION_CONFIG.NAME_MIN_LENGTH &&
399
+ trimmedName.length <= VALIDATION_CONFIG.NAME_MAX_LENGTH &&
400
+ !VALIDATION_CONFIG.RESERVED_NAMES.has(trimmedName) &&
401
+ /^[a-zA-Z0-9_-]+$/.test(trimmedName));
402
+ }
403
+ /**
404
+ * Suggest alternative tool names if the provided name is invalid
405
+ */
406
+ export function suggestToolNames(baseName) {
407
+ if (!baseName || typeof baseName !== "string") {
408
+ return VALIDATION_CONFIG.RECOMMENDED_PATTERNS.slice(0, 3);
409
+ }
410
+ const cleanBase = baseName.toLowerCase().replace(/[^a-z0-9]/g, "_");
411
+ const suggestions = [];
412
+ // Add suffixes if the name is reserved
413
+ if (VALIDATION_CONFIG.RESERVED_NAMES.has(cleanBase)) {
414
+ suggestions.push(`${cleanBase}_tool`, `custom_${cleanBase}`, `${cleanBase}_helper`);
415
+ }
416
+ // Add pattern-based suggestions
417
+ const patterns = ["get_", "fetch_", "create_", "update_"];
418
+ patterns.forEach((pattern) => {
419
+ if (!cleanBase.startsWith(pattern.slice(0, -1))) {
420
+ suggestions.push(`${pattern}${cleanBase}`);
421
+ }
422
+ });
423
+ // Add recommended patterns if no good suggestions
424
+ if (suggestions.length === 0) {
425
+ suggestions.push(...VALIDATION_CONFIG.RECOMMENDED_PATTERNS.slice(0, 3));
426
+ }
427
+ return suggestions.slice(0, 5); // Limit to 5 suggestions
186
428
  }
@@ -19,6 +19,11 @@ export declare class TelemetryService {
19
19
  private mcpToolCalls?;
20
20
  private connectionCounter?;
21
21
  private responseTimeHistogram?;
22
+ private activeConnectionCount;
23
+ private errorCount;
24
+ private requestCount;
25
+ private totalResponseTime;
26
+ private responseTimeCount;
22
27
  private constructor();
23
28
  static getInstance(): TelemetryService;
24
29
  private isTelemetryEnabled;
@@ -30,6 +35,7 @@ export declare class TelemetryService {
30
35
  recordAIError(provider: string, error: Error): void;
31
36
  recordMCPToolCall(toolName: string, duration: number, success: boolean): void;
32
37
  recordConnection(type: "websocket" | "sse" | "http"): void;
38
+ recordConnectionClosed(type: "websocket" | "sse" | "http"): void;
33
39
  recordResponseTime(endpoint: string, method: string, duration: number): void;
34
40
  recordCustomMetric(name: string, value: number, labels?: Record<string, string>): void;
35
41
  recordCustomHistogram(name: string, value: number, labels?: Record<string, string>): void;
@@ -21,6 +21,12 @@ export class TelemetryService {
21
21
  mcpToolCalls;
22
22
  connectionCounter;
23
23
  responseTimeHistogram;
24
+ // Runtime metrics tracking
25
+ activeConnectionCount = 0;
26
+ errorCount = 0;
27
+ requestCount = 0;
28
+ totalResponseTime = 0;
29
+ responseTimeCount = 0;
24
30
  constructor() {
25
31
  // Check if telemetry is enabled
26
32
  this.enabled = this.isTelemetryEnabled();
@@ -135,6 +141,10 @@ export class TelemetryService {
135
141
  }
136
142
  // Metrics Recording (NO-OP when disabled)
137
143
  recordAIRequest(provider, model, tokens, duration) {
144
+ // Track runtime metrics
145
+ this.requestCount++;
146
+ this.totalResponseTime += duration;
147
+ this.responseTimeCount++;
138
148
  if (!this.enabled || !this.aiRequestCounter) {
139
149
  return;
140
150
  }
@@ -144,6 +154,8 @@ export class TelemetryService {
144
154
  this.aiTokensUsed?.add(tokens, labels);
145
155
  }
146
156
  recordAIError(provider, error) {
157
+ // Track runtime metrics
158
+ this.errorCount++;
147
159
  if (!this.enabled || !this.aiProviderErrors) {
148
160
  return;
149
161
  }
@@ -164,12 +176,29 @@ export class TelemetryService {
164
176
  });
165
177
  }
166
178
  recordConnection(type) {
179
+ // Track runtime metrics
180
+ this.activeConnectionCount++;
167
181
  if (!this.enabled || !this.connectionCounter) {
168
182
  return;
169
183
  }
170
184
  this.connectionCounter.add(1, { connection_type: type });
171
185
  }
186
+ recordConnectionClosed(type) {
187
+ // Track runtime metrics
188
+ this.activeConnectionCount = Math.max(0, this.activeConnectionCount - 1);
189
+ if (!this.enabled || !this.connectionCounter) {
190
+ return;
191
+ }
192
+ // Optionally record disconnection metrics if needed
193
+ this.connectionCounter.add(-1, {
194
+ connection_type: type,
195
+ event: "disconnect",
196
+ });
197
+ }
172
198
  recordResponseTime(endpoint, method, duration) {
199
+ // Track runtime metrics
200
+ this.totalResponseTime += duration;
201
+ this.responseTimeCount++;
173
202
  if (!this.enabled || !this.responseTimeHistogram) {
174
203
  return;
175
204
  }
@@ -201,13 +230,19 @@ export class TelemetryService {
201
230
  // Health Checks
202
231
  async getHealthMetrics() {
203
232
  const memoryUsage = process.memoryUsage();
233
+ // Calculate error rate as percentage of errors vs total requests
234
+ const errorRate = this.requestCount > 0 ? (this.errorCount / this.requestCount) * 100 : 0;
235
+ // Calculate average response time
236
+ const averageResponseTime = this.responseTimeCount > 0
237
+ ? this.totalResponseTime / this.responseTimeCount
238
+ : 0;
204
239
  return {
205
240
  timestamp: Date.now(),
206
241
  memoryUsage,
207
242
  uptime: process.uptime(),
208
- activeConnections: 0, // Would need to be provided by calling code
209
- errorRate: 0, // Would need to be calculated from metrics
210
- averageResponseTime: 0, // Would need to be calculated from metrics
243
+ activeConnections: this.activeConnectionCount,
244
+ errorRate: Math.round(errorRate * 100) / 100, // Round to 2 decimal places
245
+ averageResponseTime: Math.round(averageResponseTime * 100) / 100, // Round to 2 decimal places
211
246
  };
212
247
  }
213
248
  // Telemetry Status
@@ -2,7 +2,7 @@
2
2
  * Context Types for NeuroLink - Factory Pattern Implementation
3
3
  * Provides type-safe context integration for AI generation
4
4
  */
5
- import { JsonObject } from "./common.js";
5
+ import type { JsonObject } from "./common.js";
6
6
  /**
7
7
  * Base context interface for all AI operations
8
8
  */
@@ -26,7 +26,7 @@ export interface BaseContext {
26
26
  /**
27
27
  * Context integration mode types
28
28
  */
29
- export type ContextIntegrationMode = "prompt_prefix" | "prompt_suffix" | "system_prompt" | "metadata_only" | "structured_prompt" | "none";
29
+ type ContextIntegrationMode = "prompt_prefix" | "prompt_suffix" | "system_prompt" | "metadata_only" | "structured_prompt" | "none";
30
30
  /**
31
31
  * Context configuration for AI generation
32
32
  */
@@ -41,7 +41,7 @@ export interface ContextConfig {
41
41
  /**
42
42
  * Context processing result
43
43
  */
44
- export interface ProcessedContext {
44
+ interface ProcessedContext {
45
45
  originalContext: BaseContext;
46
46
  processedContext: string | null;
47
47
  config: ContextConfig;
@@ -52,10 +52,58 @@ export interface ProcessedContext {
52
52
  mode: ContextIntegrationMode;
53
53
  };
54
54
  }
55
+ /**
56
+ * Configuration for framework fields exclusion
57
+ * Can be customized per application or environment
58
+ */
59
+ export interface FrameworkFieldsConfig {
60
+ defaultFields: string[];
61
+ additionalFields?: string[];
62
+ overrideFields?: string[];
63
+ includeFields?: string[];
64
+ }
55
65
  /**
56
66
  * Factory for context processing
57
67
  */
58
68
  export declare class ContextFactory {
69
+ /**
70
+ * Default framework fields configuration
71
+ */
72
+ static readonly DEFAULT_FRAMEWORK_FIELDS: FrameworkFieldsConfig;
73
+ /**
74
+ * Current framework fields configuration
75
+ */
76
+ private static frameworkFieldsConfig;
77
+ /**
78
+ * Flag to track if framework fields have been initialized
79
+ */
80
+ private static isFrameworkFieldsInitialized;
81
+ /**
82
+ * Configure framework fields for exclusion from custom data
83
+ */
84
+ static configureFrameworkFields(config: Partial<FrameworkFieldsConfig>): void;
85
+ /**
86
+ * Get current framework fields configuration
87
+ * Ensures lazy initialization if not already loaded
88
+ */
89
+ static getFrameworkFieldsConfig(): FrameworkFieldsConfig;
90
+ /**
91
+ * Reset framework fields configuration to default
92
+ */
93
+ static resetFrameworkFieldsConfig(): void;
94
+ /**
95
+ * Load framework fields configuration from environment variables
96
+ * Supports NEUROLINK_CONTEXT_EXCLUDE_FIELDS and NEUROLINK_CONTEXT_INCLUDE_FIELDS
97
+ */
98
+ static loadFrameworkFieldsFromEnv(): void;
99
+ /**
100
+ * Add additional fields to exclude
101
+ */
102
+ static addFrameworkFieldsToExclude(fields: string[]): void;
103
+ /**
104
+ * Add fields to include (override exclusion)
105
+ */
106
+ static addFrameworkFieldsToInclude(fields: string[]): void;
59
107
  /**
60
108
  * Default context configuration
61
109
  */
@@ -98,13 +146,29 @@ export declare class ContextFactory {
98
146
  static extractEvaluationContext(context: BaseContext): JsonObject;
99
147
  }
100
148
  /**
101
- * Type guard to check if value is valid context
149
+ * Context conversion utilities for domain-specific data
150
+ * Replaces hardcoded business context with generic domain context
102
151
  */
103
- export declare function isValidContext(value: unknown): value is BaseContext;
104
- /**
105
- * Context integration options for AI generation
106
- */
107
- export interface ContextIntegrationOptions {
108
- context?: BaseContext;
109
- contextConfig?: Partial<ContextConfig>;
152
+ import type { ExecutionContext } from "../mcp/contracts/mcpContract.js";
153
+ interface ContextConversionOptions {
154
+ preserveLegacyFields?: boolean;
155
+ validateDomainData?: boolean;
156
+ includeMetadata?: boolean;
157
+ }
158
+ export declare class ContextConverter {
159
+ /**
160
+ * Convert legacy business context to generic domain context
161
+ * Based on business context patterns
162
+ */
163
+ static convertBusinessContext(legacyContext: Record<string, unknown>, domainType: string, options?: ContextConversionOptions): ExecutionContext;
164
+ /**
165
+ * Create execution context for any domain
166
+ */
167
+ static createDomainContext(domainType: string, domainData: Record<string, unknown>, sessionInfo?: {
168
+ sessionId?: string;
169
+ userId?: string;
170
+ }): ExecutionContext;
171
+ private static inferProvider;
172
+ private static extractCustomData;
110
173
  }
174
+ export {};