@juspay/neurolink 9.15.0 → 9.16.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 (193) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/adapters/video/videoAnalyzer.d.ts +1 -1
  3. package/dist/adapters/video/videoAnalyzer.js +10 -8
  4. package/dist/cli/commands/setup-anthropic.js +1 -14
  5. package/dist/cli/commands/setup-azure.js +1 -12
  6. package/dist/cli/commands/setup-bedrock.js +1 -9
  7. package/dist/cli/commands/setup-google-ai.js +1 -12
  8. package/dist/cli/commands/setup-openai.js +1 -14
  9. package/dist/cli/commands/workflow.d.ts +27 -0
  10. package/dist/cli/commands/workflow.js +216 -0
  11. package/dist/cli/factories/commandFactory.js +79 -20
  12. package/dist/cli/index.js +0 -1
  13. package/dist/cli/parser.js +4 -1
  14. package/dist/cli/utils/maskCredential.d.ts +11 -0
  15. package/dist/cli/utils/maskCredential.js +23 -0
  16. package/dist/constants/contextWindows.js +107 -16
  17. package/dist/constants/enums.d.ts +99 -15
  18. package/dist/constants/enums.js +152 -22
  19. package/dist/context/budgetChecker.js +1 -1
  20. package/dist/context/contextCompactor.js +31 -4
  21. package/dist/context/emergencyTruncation.d.ts +21 -0
  22. package/dist/context/emergencyTruncation.js +88 -0
  23. package/dist/context/errorDetection.d.ts +16 -0
  24. package/dist/context/errorDetection.js +48 -1
  25. package/dist/context/errors.d.ts +19 -0
  26. package/dist/context/errors.js +21 -0
  27. package/dist/context/stages/slidingWindowTruncator.d.ts +6 -0
  28. package/dist/context/stages/slidingWindowTruncator.js +159 -24
  29. package/dist/core/baseProvider.js +306 -200
  30. package/dist/core/conversationMemoryManager.js +104 -61
  31. package/dist/core/evaluationProviders.js +16 -33
  32. package/dist/core/factory.js +237 -164
  33. package/dist/core/modules/GenerationHandler.js +175 -116
  34. package/dist/core/modules/MessageBuilder.js +222 -170
  35. package/dist/core/modules/StreamHandler.d.ts +1 -0
  36. package/dist/core/modules/StreamHandler.js +95 -27
  37. package/dist/core/modules/TelemetryHandler.d.ts +10 -1
  38. package/dist/core/modules/TelemetryHandler.js +25 -7
  39. package/dist/core/modules/ToolsManager.js +115 -191
  40. package/dist/core/redisConversationMemoryManager.js +418 -282
  41. package/dist/factories/providerRegistry.d.ts +5 -0
  42. package/dist/factories/providerRegistry.js +20 -2
  43. package/dist/index.d.ts +2 -2
  44. package/dist/index.js +4 -2
  45. package/dist/lib/adapters/video/videoAnalyzer.d.ts +1 -1
  46. package/dist/lib/adapters/video/videoAnalyzer.js +10 -8
  47. package/dist/lib/constants/contextWindows.js +107 -16
  48. package/dist/lib/constants/enums.d.ts +99 -15
  49. package/dist/lib/constants/enums.js +152 -22
  50. package/dist/lib/context/budgetChecker.js +1 -1
  51. package/dist/lib/context/contextCompactor.js +31 -4
  52. package/dist/lib/context/emergencyTruncation.d.ts +21 -0
  53. package/dist/lib/context/emergencyTruncation.js +89 -0
  54. package/dist/lib/context/errorDetection.d.ts +16 -0
  55. package/dist/lib/context/errorDetection.js +48 -1
  56. package/dist/lib/context/errors.d.ts +19 -0
  57. package/dist/lib/context/errors.js +22 -0
  58. package/dist/lib/context/stages/slidingWindowTruncator.d.ts +6 -0
  59. package/dist/lib/context/stages/slidingWindowTruncator.js +159 -24
  60. package/dist/lib/core/baseProvider.js +306 -200
  61. package/dist/lib/core/conversationMemoryManager.js +104 -61
  62. package/dist/lib/core/evaluationProviders.js +16 -33
  63. package/dist/lib/core/factory.js +237 -164
  64. package/dist/lib/core/modules/GenerationHandler.js +175 -116
  65. package/dist/lib/core/modules/MessageBuilder.js +222 -170
  66. package/dist/lib/core/modules/StreamHandler.d.ts +1 -0
  67. package/dist/lib/core/modules/StreamHandler.js +95 -27
  68. package/dist/lib/core/modules/TelemetryHandler.d.ts +10 -1
  69. package/dist/lib/core/modules/TelemetryHandler.js +25 -7
  70. package/dist/lib/core/modules/ToolsManager.js +115 -191
  71. package/dist/lib/core/redisConversationMemoryManager.js +418 -282
  72. package/dist/lib/factories/providerRegistry.d.ts +5 -0
  73. package/dist/lib/factories/providerRegistry.js +20 -2
  74. package/dist/lib/index.d.ts +2 -2
  75. package/dist/lib/index.js +4 -2
  76. package/dist/lib/mcp/externalServerManager.js +66 -0
  77. package/dist/lib/mcp/mcpCircuitBreaker.js +24 -0
  78. package/dist/lib/mcp/mcpClientFactory.js +16 -0
  79. package/dist/lib/mcp/toolDiscoveryService.js +32 -6
  80. package/dist/lib/mcp/toolRegistry.js +193 -123
  81. package/dist/lib/neurolink.d.ts +6 -0
  82. package/dist/lib/neurolink.js +1162 -646
  83. package/dist/lib/providers/amazonBedrock.d.ts +1 -1
  84. package/dist/lib/providers/amazonBedrock.js +521 -319
  85. package/dist/lib/providers/anthropic.js +73 -17
  86. package/dist/lib/providers/anthropicBaseProvider.js +77 -17
  87. package/dist/lib/providers/googleAiStudio.d.ts +1 -1
  88. package/dist/lib/providers/googleAiStudio.js +292 -227
  89. package/dist/lib/providers/googleVertex.d.ts +36 -1
  90. package/dist/lib/providers/googleVertex.js +553 -260
  91. package/dist/lib/providers/ollama.js +329 -278
  92. package/dist/lib/providers/openAI.js +77 -19
  93. package/dist/lib/providers/sagemaker/parsers.js +3 -3
  94. package/dist/lib/providers/sagemaker/streaming.js +3 -3
  95. package/dist/lib/proxy/proxyFetch.js +81 -48
  96. package/dist/lib/rag/ChunkerFactory.js +1 -1
  97. package/dist/lib/rag/chunkers/MarkdownChunker.d.ts +22 -0
  98. package/dist/lib/rag/chunkers/MarkdownChunker.js +213 -9
  99. package/dist/lib/rag/chunking/markdownChunker.d.ts +16 -0
  100. package/dist/lib/rag/chunking/markdownChunker.js +174 -2
  101. package/dist/lib/rag/pipeline/contextAssembly.js +2 -1
  102. package/dist/lib/rag/ragIntegration.d.ts +18 -1
  103. package/dist/lib/rag/ragIntegration.js +94 -14
  104. package/dist/lib/rag/retrieval/vectorQueryTool.js +21 -4
  105. package/dist/lib/server/abstract/baseServerAdapter.js +4 -1
  106. package/dist/lib/server/adapters/fastifyAdapter.js +35 -30
  107. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +32 -0
  108. package/dist/lib/services/server/ai/observability/instrumentation.js +39 -0
  109. package/dist/lib/telemetry/attributes.d.ts +52 -0
  110. package/dist/lib/telemetry/attributes.js +61 -0
  111. package/dist/lib/telemetry/index.d.ts +3 -0
  112. package/dist/lib/telemetry/index.js +3 -0
  113. package/dist/lib/telemetry/telemetryService.d.ts +6 -0
  114. package/dist/lib/telemetry/telemetryService.js +6 -0
  115. package/dist/lib/telemetry/tracers.d.ts +15 -0
  116. package/dist/lib/telemetry/tracers.js +17 -0
  117. package/dist/lib/telemetry/withSpan.d.ts +9 -0
  118. package/dist/lib/telemetry/withSpan.js +35 -0
  119. package/dist/lib/types/contextTypes.d.ts +10 -0
  120. package/dist/lib/types/streamTypes.d.ts +14 -0
  121. package/dist/lib/utils/conversationMemory.js +121 -82
  122. package/dist/lib/utils/logger.d.ts +5 -0
  123. package/dist/lib/utils/logger.js +50 -2
  124. package/dist/lib/utils/messageBuilder.js +22 -42
  125. package/dist/lib/utils/modelDetection.js +3 -3
  126. package/dist/lib/utils/providerRetry.d.ts +41 -0
  127. package/dist/lib/utils/providerRetry.js +114 -0
  128. package/dist/lib/utils/retryability.d.ts +14 -0
  129. package/dist/lib/utils/retryability.js +23 -0
  130. package/dist/lib/utils/sanitizers/svg.js +4 -5
  131. package/dist/lib/utils/tokenEstimation.d.ts +11 -1
  132. package/dist/lib/utils/tokenEstimation.js +19 -4
  133. package/dist/lib/utils/videoAnalysisProcessor.js +7 -3
  134. package/dist/mcp/externalServerManager.js +66 -0
  135. package/dist/mcp/mcpCircuitBreaker.js +24 -0
  136. package/dist/mcp/mcpClientFactory.js +16 -0
  137. package/dist/mcp/toolDiscoveryService.js +32 -6
  138. package/dist/mcp/toolRegistry.js +193 -123
  139. package/dist/neurolink.d.ts +6 -0
  140. package/dist/neurolink.js +1162 -646
  141. package/dist/providers/amazonBedrock.d.ts +1 -1
  142. package/dist/providers/amazonBedrock.js +521 -319
  143. package/dist/providers/anthropic.js +73 -17
  144. package/dist/providers/anthropicBaseProvider.js +77 -17
  145. package/dist/providers/googleAiStudio.d.ts +1 -1
  146. package/dist/providers/googleAiStudio.js +292 -227
  147. package/dist/providers/googleVertex.d.ts +36 -1
  148. package/dist/providers/googleVertex.js +553 -260
  149. package/dist/providers/ollama.js +329 -278
  150. package/dist/providers/openAI.js +77 -19
  151. package/dist/providers/sagemaker/parsers.js +3 -3
  152. package/dist/providers/sagemaker/streaming.js +3 -3
  153. package/dist/proxy/proxyFetch.js +81 -48
  154. package/dist/rag/ChunkerFactory.js +1 -1
  155. package/dist/rag/chunkers/MarkdownChunker.d.ts +22 -0
  156. package/dist/rag/chunkers/MarkdownChunker.js +213 -9
  157. package/dist/rag/chunking/markdownChunker.d.ts +16 -0
  158. package/dist/rag/chunking/markdownChunker.js +174 -2
  159. package/dist/rag/pipeline/contextAssembly.js +2 -1
  160. package/dist/rag/ragIntegration.d.ts +18 -1
  161. package/dist/rag/ragIntegration.js +94 -14
  162. package/dist/rag/retrieval/vectorQueryTool.js +21 -4
  163. package/dist/server/abstract/baseServerAdapter.js +4 -1
  164. package/dist/server/adapters/fastifyAdapter.js +35 -30
  165. package/dist/services/server/ai/observability/instrumentation.d.ts +32 -0
  166. package/dist/services/server/ai/observability/instrumentation.js +39 -0
  167. package/dist/telemetry/attributes.d.ts +52 -0
  168. package/dist/telemetry/attributes.js +60 -0
  169. package/dist/telemetry/index.d.ts +3 -0
  170. package/dist/telemetry/index.js +3 -0
  171. package/dist/telemetry/telemetryService.d.ts +6 -0
  172. package/dist/telemetry/telemetryService.js +6 -0
  173. package/dist/telemetry/tracers.d.ts +15 -0
  174. package/dist/telemetry/tracers.js +16 -0
  175. package/dist/telemetry/withSpan.d.ts +9 -0
  176. package/dist/telemetry/withSpan.js +34 -0
  177. package/dist/types/contextTypes.d.ts +10 -0
  178. package/dist/types/streamTypes.d.ts +14 -0
  179. package/dist/utils/conversationMemory.js +121 -82
  180. package/dist/utils/logger.d.ts +5 -0
  181. package/dist/utils/logger.js +50 -2
  182. package/dist/utils/messageBuilder.js +22 -42
  183. package/dist/utils/modelDetection.js +3 -3
  184. package/dist/utils/providerRetry.d.ts +41 -0
  185. package/dist/utils/providerRetry.js +113 -0
  186. package/dist/utils/retryability.d.ts +14 -0
  187. package/dist/utils/retryability.js +22 -0
  188. package/dist/utils/sanitizers/svg.js +4 -5
  189. package/dist/utils/tokenEstimation.d.ts +11 -1
  190. package/dist/utils/tokenEstimation.js +19 -4
  191. package/dist/utils/videoAnalysisProcessor.js +7 -3
  192. package/dist/workflow/config.d.ts +26 -26
  193. package/package.json +1 -1
@@ -4,39 +4,174 @@
4
4
  * Non-destructive fallback: tags oldest messages as truncated
5
5
  * instead of deleting them. Always preserves first message pair.
6
6
  * Removes messages in pairs to maintain role alternation.
7
+ *
8
+ * Features:
9
+ * - Adaptive truncation (PERF-001): calculates fraction from actual overage
10
+ * instead of fixed 50%, with iterative refinement up to 3 passes.
11
+ * - Small conversation handling (BUG-005): for <= 4 messages, truncates
12
+ * message content proportionally instead of returning no-op.
7
13
  */
8
14
  import { randomUUID } from "crypto";
15
+ import { estimateTokens, estimateMessagesTokens, truncateToTokenBudget, } from "../../utils/tokenEstimation.js";
16
+ import { logger } from "../../utils/logger.js";
9
17
  const TRUNCATION_MARKER_CONTENT = "[Earlier conversation history was truncated to fit within context limits]";
18
+ /**
19
+ * For conversations with <= 4 messages that exceed token budget,
20
+ * truncate the CONTENT of the longest messages rather than removing messages.
21
+ *
22
+ * Strategy:
23
+ * 1. Calculate each message's proportional share of the token budget
24
+ * 2. Truncate messages that exceed their share using truncateToTokenBudget()
25
+ * 3. Never truncate messages below 200 tokens (preserve minimum context)
26
+ */
27
+ function truncateSmallConversation(messages, config) {
28
+ // If no target tokens provided, we can't do content truncation
29
+ if (!config?.targetTokens) {
30
+ return { truncated: false, messages, messagesRemoved: 0 };
31
+ }
32
+ const provider = config.provider;
33
+ const targetTokens = config.targetTokens;
34
+ const currentTokens = estimateMessagesTokens(messages, provider);
35
+ if (currentTokens <= targetTokens) {
36
+ return { truncated: false, messages, messagesRemoved: 0 };
37
+ }
38
+ const MINIMUM_MSG_TOKENS = 200;
39
+ const FRAMING_OVERHEAD = 24 + messages.length * 4; // conversation + per-message overhead
40
+ // Available budget for actual content
41
+ const contentBudget = targetTokens - FRAMING_OVERHEAD;
42
+ if (contentBudget <= 0) {
43
+ return { truncated: false, messages, messagesRemoved: 0 };
44
+ }
45
+ // Calculate current content tokens per message
46
+ const msgTokens = messages.map((msg) => estimateTokens(msg.content, provider));
47
+ const totalContentTokens = msgTokens.reduce((sum, t) => sum + t, 0);
48
+ // Each message gets a proportional share of the content budget
49
+ const result = [...messages];
50
+ let totalSaved = 0;
51
+ for (let i = 0; i < result.length; i++) {
52
+ const msg = result[i];
53
+ // Don't truncate system/summary messages
54
+ if (msg.role === "system" || msg.metadata?.isSummary) {
55
+ continue;
56
+ }
57
+ const proportionalBudget = Math.floor((msgTokens[i] / totalContentTokens) * contentBudget);
58
+ const msgBudget = Math.max(MINIMUM_MSG_TOKENS, proportionalBudget);
59
+ if (msgTokens[i] > msgBudget) {
60
+ const truncated = truncateToTokenBudget(msg.content, msgBudget, provider);
61
+ if (truncated.truncated) {
62
+ totalSaved += msgTokens[i] - estimateTokens(truncated.text, provider);
63
+ result[i] = {
64
+ ...msg,
65
+ content: truncated.text,
66
+ metadata: { ...msg.metadata, truncated: true },
67
+ };
68
+ }
69
+ }
70
+ }
71
+ if (totalSaved > 0) {
72
+ const finalTokens = estimateMessagesTokens(result, provider);
73
+ logger.info("[Truncation] Small conversation content truncated", {
74
+ messageCount: messages.length,
75
+ tokensSaved: totalSaved,
76
+ targetTokens,
77
+ finalTokens,
78
+ });
79
+ return {
80
+ truncated: finalTokens <= targetTokens,
81
+ messages: result,
82
+ messagesRemoved: 0, // No messages removed, only content truncated
83
+ };
84
+ }
85
+ return { truncated: false, messages, messagesRemoved: 0 };
86
+ }
10
87
  export function truncateWithSlidingWindow(messages, config) {
11
- const fraction = config?.fraction ?? 0.5;
12
88
  if (messages.length <= 4) {
13
- return { truncated: false, messages, messagesRemoved: 0 };
89
+ // Delegate to content truncation for small conversations (BUG-005)
90
+ return truncateSmallConversation(messages, config);
91
+ }
92
+ // ADAPTIVE MODE: calculate fraction from actual overage (PERF-001)
93
+ let fraction;
94
+ if (config?.currentTokens &&
95
+ config?.targetTokens &&
96
+ config.currentTokens > config.targetTokens) {
97
+ const overageRatio = (config.currentTokens - config.targetTokens) / config.currentTokens;
98
+ const buffer = config?.adaptiveBuffer ?? 0.15;
99
+ // Required fraction = overage ratio + buffer, clamped to [0.1, 0.9]
100
+ fraction = Math.min(0.9, Math.max(0.1, overageRatio + buffer));
101
+ logger.info("[Truncation] Adaptive fraction calculated", {
102
+ currentTokens: config.currentTokens,
103
+ targetTokens: config.targetTokens,
104
+ overageRatio: Math.round(overageRatio * 100),
105
+ fraction: Math.round(fraction * 100),
106
+ });
107
+ }
108
+ else {
109
+ // Fallback to configured or default fraction
110
+ fraction = config?.fraction ?? 0.5;
14
111
  }
15
112
  // Always preserve first user-assistant pair
16
113
  const firstPair = messages.slice(0, 2);
17
- // Calculate how many messages to remove from the middle
18
114
  const remainingMessages = messages.slice(2);
19
- const removeCount = Math.floor(remainingMessages.length * fraction);
20
- // Ensure we remove an even number to maintain role alternation
21
- const evenRemoveCount = removeCount - (removeCount % 2);
22
- if (evenRemoveCount <= 0) {
23
- return { truncated: false, messages, messagesRemoved: 0 };
115
+ // ITERATIVE: if first pass isn't enough, increase fraction
116
+ const maxIterations = config?.maxIterations ?? 3;
117
+ let currentFraction = fraction;
118
+ for (let iteration = 0; iteration < maxIterations; iteration++) {
119
+ const removeCount = Math.floor(remainingMessages.length * currentFraction);
120
+ const evenRemoveCount = removeCount - (removeCount % 2);
121
+ if (evenRemoveCount <= 0) {
122
+ break;
123
+ }
124
+ const keptAfterTruncation = remainingMessages.slice(evenRemoveCount);
125
+ const truncationMarker = {
126
+ id: `truncation-${randomUUID()}`,
127
+ role: "system",
128
+ content: TRUNCATION_MARKER_CONTENT,
129
+ timestamp: new Date().toISOString(),
130
+ metadata: { isSummary: false, truncated: true },
131
+ };
132
+ const candidateMessages = [
133
+ ...firstPair,
134
+ truncationMarker,
135
+ ...keptAfterTruncation,
136
+ ];
137
+ // If we have token targets, verify the result fits
138
+ if (config?.targetTokens) {
139
+ const candidateTokens = estimateMessagesTokens(candidateMessages, config.provider);
140
+ if (candidateTokens <= config.targetTokens) {
141
+ return {
142
+ truncated: true,
143
+ messages: candidateMessages,
144
+ messagesRemoved: evenRemoveCount,
145
+ };
146
+ }
147
+ // Not enough -- increase fraction by 25% for next iteration
148
+ currentFraction = Math.min(0.95, currentFraction + 0.25);
149
+ continue;
150
+ }
151
+ // No token targets -- single-pass with calculated fraction
152
+ return {
153
+ truncated: true,
154
+ messages: candidateMessages,
155
+ messagesRemoved: evenRemoveCount,
156
+ };
24
157
  }
25
- const keptAfterTruncation = remainingMessages.slice(evenRemoveCount);
26
- // Create truncation marker
27
- const truncationMarker = {
28
- id: `truncation-${randomUUID()}`,
29
- role: "system",
30
- content: TRUNCATION_MARKER_CONTENT,
31
- timestamp: new Date().toISOString(),
32
- metadata: {
33
- isSummary: false,
158
+ // All iterations exhausted -- return best effort (most aggressive truncation)
159
+ const maxRemove = Math.floor(remainingMessages.length * 0.95);
160
+ const evenMaxRemove = maxRemove - (maxRemove % 2);
161
+ if (evenMaxRemove > 0) {
162
+ const keptMessages = remainingMessages.slice(evenMaxRemove);
163
+ const truncationMarker = {
164
+ id: `truncation-${randomUUID()}`,
165
+ role: "system",
166
+ content: TRUNCATION_MARKER_CONTENT,
167
+ timestamp: new Date().toISOString(),
168
+ metadata: { isSummary: false, truncated: true },
169
+ };
170
+ return {
34
171
  truncated: true,
35
- },
36
- };
37
- return {
38
- truncated: true,
39
- messages: [...firstPair, truncationMarker, ...keptAfterTruncation],
40
- messagesRemoved: evenRemoveCount,
41
- };
172
+ messages: [...firstPair, truncationMarker, ...keptMessages],
173
+ messagesRemoved: evenMaxRemove,
174
+ };
175
+ }
176
+ return { truncated: false, messages, messagesRemoved: 0 };
42
177
  }