@juspay/neurolink 7.6.0 → 7.7.0

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