@juspay/neurolink 9.15.0 → 9.17.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 (196) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +22 -20
  3. package/dist/adapters/video/videoAnalyzer.d.ts +1 -1
  4. package/dist/adapters/video/videoAnalyzer.js +10 -8
  5. package/dist/cli/commands/setup-anthropic.js +1 -14
  6. package/dist/cli/commands/setup-azure.js +1 -12
  7. package/dist/cli/commands/setup-bedrock.js +1 -9
  8. package/dist/cli/commands/setup-google-ai.js +1 -12
  9. package/dist/cli/commands/setup-openai.js +1 -14
  10. package/dist/cli/commands/workflow.d.ts +27 -0
  11. package/dist/cli/commands/workflow.js +216 -0
  12. package/dist/cli/factories/commandFactory.js +79 -20
  13. package/dist/cli/index.js +0 -1
  14. package/dist/cli/parser.js +4 -1
  15. package/dist/cli/utils/maskCredential.d.ts +11 -0
  16. package/dist/cli/utils/maskCredential.js +23 -0
  17. package/dist/constants/contextWindows.js +107 -16
  18. package/dist/constants/enums.d.ts +99 -15
  19. package/dist/constants/enums.js +152 -22
  20. package/dist/context/budgetChecker.js +1 -1
  21. package/dist/context/contextCompactor.js +31 -4
  22. package/dist/context/emergencyTruncation.d.ts +21 -0
  23. package/dist/context/emergencyTruncation.js +88 -0
  24. package/dist/context/errorDetection.d.ts +16 -0
  25. package/dist/context/errorDetection.js +48 -1
  26. package/dist/context/errors.d.ts +19 -0
  27. package/dist/context/errors.js +21 -0
  28. package/dist/context/stages/slidingWindowTruncator.d.ts +6 -0
  29. package/dist/context/stages/slidingWindowTruncator.js +159 -24
  30. package/dist/context/stages/structuredSummarizer.js +2 -2
  31. package/dist/core/baseProvider.js +306 -200
  32. package/dist/core/conversationMemoryManager.js +104 -61
  33. package/dist/core/evaluationProviders.js +16 -33
  34. package/dist/core/factory.js +237 -164
  35. package/dist/core/modules/GenerationHandler.js +175 -116
  36. package/dist/core/modules/MessageBuilder.js +222 -170
  37. package/dist/core/modules/StreamHandler.d.ts +1 -0
  38. package/dist/core/modules/StreamHandler.js +95 -27
  39. package/dist/core/modules/TelemetryHandler.d.ts +10 -1
  40. package/dist/core/modules/TelemetryHandler.js +25 -7
  41. package/dist/core/modules/ToolsManager.js +115 -191
  42. package/dist/core/redisConversationMemoryManager.js +418 -282
  43. package/dist/factories/providerRegistry.d.ts +5 -0
  44. package/dist/factories/providerRegistry.js +20 -2
  45. package/dist/index.d.ts +2 -2
  46. package/dist/index.js +4 -2
  47. package/dist/lib/adapters/video/videoAnalyzer.d.ts +1 -1
  48. package/dist/lib/adapters/video/videoAnalyzer.js +10 -8
  49. package/dist/lib/constants/contextWindows.js +107 -16
  50. package/dist/lib/constants/enums.d.ts +99 -15
  51. package/dist/lib/constants/enums.js +152 -22
  52. package/dist/lib/context/budgetChecker.js +1 -1
  53. package/dist/lib/context/contextCompactor.js +31 -4
  54. package/dist/lib/context/emergencyTruncation.d.ts +21 -0
  55. package/dist/lib/context/emergencyTruncation.js +89 -0
  56. package/dist/lib/context/errorDetection.d.ts +16 -0
  57. package/dist/lib/context/errorDetection.js +48 -1
  58. package/dist/lib/context/errors.d.ts +19 -0
  59. package/dist/lib/context/errors.js +22 -0
  60. package/dist/lib/context/stages/slidingWindowTruncator.d.ts +6 -0
  61. package/dist/lib/context/stages/slidingWindowTruncator.js +159 -24
  62. package/dist/lib/context/stages/structuredSummarizer.js +2 -2
  63. package/dist/lib/core/baseProvider.js +306 -200
  64. package/dist/lib/core/conversationMemoryManager.js +104 -61
  65. package/dist/lib/core/evaluationProviders.js +16 -33
  66. package/dist/lib/core/factory.js +237 -164
  67. package/dist/lib/core/modules/GenerationHandler.js +175 -116
  68. package/dist/lib/core/modules/MessageBuilder.js +222 -170
  69. package/dist/lib/core/modules/StreamHandler.d.ts +1 -0
  70. package/dist/lib/core/modules/StreamHandler.js +95 -27
  71. package/dist/lib/core/modules/TelemetryHandler.d.ts +10 -1
  72. package/dist/lib/core/modules/TelemetryHandler.js +25 -7
  73. package/dist/lib/core/modules/ToolsManager.js +115 -191
  74. package/dist/lib/core/redisConversationMemoryManager.js +418 -282
  75. package/dist/lib/factories/providerRegistry.d.ts +5 -0
  76. package/dist/lib/factories/providerRegistry.js +20 -2
  77. package/dist/lib/index.d.ts +2 -2
  78. package/dist/lib/index.js +4 -2
  79. package/dist/lib/mcp/externalServerManager.js +66 -0
  80. package/dist/lib/mcp/mcpCircuitBreaker.js +24 -0
  81. package/dist/lib/mcp/mcpClientFactory.js +16 -0
  82. package/dist/lib/mcp/toolDiscoveryService.js +32 -6
  83. package/dist/lib/mcp/toolRegistry.js +193 -123
  84. package/dist/lib/neurolink.d.ts +6 -0
  85. package/dist/lib/neurolink.js +1162 -646
  86. package/dist/lib/providers/amazonBedrock.d.ts +1 -1
  87. package/dist/lib/providers/amazonBedrock.js +521 -319
  88. package/dist/lib/providers/anthropic.js +73 -17
  89. package/dist/lib/providers/anthropicBaseProvider.js +77 -17
  90. package/dist/lib/providers/googleAiStudio.d.ts +1 -1
  91. package/dist/lib/providers/googleAiStudio.js +292 -227
  92. package/dist/lib/providers/googleVertex.d.ts +36 -1
  93. package/dist/lib/providers/googleVertex.js +553 -260
  94. package/dist/lib/providers/ollama.js +329 -278
  95. package/dist/lib/providers/openAI.js +77 -19
  96. package/dist/lib/providers/sagemaker/parsers.js +3 -3
  97. package/dist/lib/providers/sagemaker/streaming.js +3 -3
  98. package/dist/lib/proxy/proxyFetch.js +81 -48
  99. package/dist/lib/rag/ChunkerFactory.js +1 -1
  100. package/dist/lib/rag/chunkers/MarkdownChunker.d.ts +22 -0
  101. package/dist/lib/rag/chunkers/MarkdownChunker.js +213 -9
  102. package/dist/lib/rag/chunking/markdownChunker.d.ts +16 -0
  103. package/dist/lib/rag/chunking/markdownChunker.js +174 -2
  104. package/dist/lib/rag/pipeline/contextAssembly.js +2 -1
  105. package/dist/lib/rag/ragIntegration.d.ts +18 -1
  106. package/dist/lib/rag/ragIntegration.js +94 -14
  107. package/dist/lib/rag/retrieval/vectorQueryTool.js +21 -4
  108. package/dist/lib/server/abstract/baseServerAdapter.js +4 -1
  109. package/dist/lib/server/adapters/fastifyAdapter.js +35 -30
  110. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +32 -0
  111. package/dist/lib/services/server/ai/observability/instrumentation.js +39 -0
  112. package/dist/lib/telemetry/attributes.d.ts +52 -0
  113. package/dist/lib/telemetry/attributes.js +61 -0
  114. package/dist/lib/telemetry/index.d.ts +3 -0
  115. package/dist/lib/telemetry/index.js +3 -0
  116. package/dist/lib/telemetry/telemetryService.d.ts +6 -0
  117. package/dist/lib/telemetry/telemetryService.js +6 -0
  118. package/dist/lib/telemetry/tracers.d.ts +15 -0
  119. package/dist/lib/telemetry/tracers.js +17 -0
  120. package/dist/lib/telemetry/withSpan.d.ts +9 -0
  121. package/dist/lib/telemetry/withSpan.js +35 -0
  122. package/dist/lib/types/contextTypes.d.ts +10 -0
  123. package/dist/lib/types/streamTypes.d.ts +14 -0
  124. package/dist/lib/utils/conversationMemory.js +123 -84
  125. package/dist/lib/utils/logger.d.ts +5 -0
  126. package/dist/lib/utils/logger.js +50 -2
  127. package/dist/lib/utils/messageBuilder.js +22 -42
  128. package/dist/lib/utils/modelDetection.js +3 -3
  129. package/dist/lib/utils/providerRetry.d.ts +41 -0
  130. package/dist/lib/utils/providerRetry.js +114 -0
  131. package/dist/lib/utils/retryability.d.ts +14 -0
  132. package/dist/lib/utils/retryability.js +23 -0
  133. package/dist/lib/utils/sanitizers/svg.js +4 -5
  134. package/dist/lib/utils/tokenEstimation.d.ts +11 -1
  135. package/dist/lib/utils/tokenEstimation.js +19 -4
  136. package/dist/lib/utils/videoAnalysisProcessor.js +7 -3
  137. package/dist/mcp/externalServerManager.js +66 -0
  138. package/dist/mcp/mcpCircuitBreaker.js +24 -0
  139. package/dist/mcp/mcpClientFactory.js +16 -0
  140. package/dist/mcp/toolDiscoveryService.js +32 -6
  141. package/dist/mcp/toolRegistry.js +193 -123
  142. package/dist/neurolink.d.ts +6 -0
  143. package/dist/neurolink.js +1162 -646
  144. package/dist/providers/amazonBedrock.d.ts +1 -1
  145. package/dist/providers/amazonBedrock.js +521 -319
  146. package/dist/providers/anthropic.js +73 -17
  147. package/dist/providers/anthropicBaseProvider.js +77 -17
  148. package/dist/providers/googleAiStudio.d.ts +1 -1
  149. package/dist/providers/googleAiStudio.js +292 -227
  150. package/dist/providers/googleVertex.d.ts +36 -1
  151. package/dist/providers/googleVertex.js +553 -260
  152. package/dist/providers/ollama.js +329 -278
  153. package/dist/providers/openAI.js +77 -19
  154. package/dist/providers/sagemaker/parsers.js +3 -3
  155. package/dist/providers/sagemaker/streaming.js +3 -3
  156. package/dist/proxy/proxyFetch.js +81 -48
  157. package/dist/rag/ChunkerFactory.js +1 -1
  158. package/dist/rag/chunkers/MarkdownChunker.d.ts +22 -0
  159. package/dist/rag/chunkers/MarkdownChunker.js +213 -9
  160. package/dist/rag/chunking/markdownChunker.d.ts +16 -0
  161. package/dist/rag/chunking/markdownChunker.js +174 -2
  162. package/dist/rag/pipeline/contextAssembly.js +2 -1
  163. package/dist/rag/ragIntegration.d.ts +18 -1
  164. package/dist/rag/ragIntegration.js +94 -14
  165. package/dist/rag/retrieval/vectorQueryTool.js +21 -4
  166. package/dist/server/abstract/baseServerAdapter.js +4 -1
  167. package/dist/server/adapters/fastifyAdapter.js +35 -30
  168. package/dist/services/server/ai/observability/instrumentation.d.ts +32 -0
  169. package/dist/services/server/ai/observability/instrumentation.js +39 -0
  170. package/dist/telemetry/attributes.d.ts +52 -0
  171. package/dist/telemetry/attributes.js +60 -0
  172. package/dist/telemetry/index.d.ts +3 -0
  173. package/dist/telemetry/index.js +3 -0
  174. package/dist/telemetry/telemetryService.d.ts +6 -0
  175. package/dist/telemetry/telemetryService.js +6 -0
  176. package/dist/telemetry/tracers.d.ts +15 -0
  177. package/dist/telemetry/tracers.js +16 -0
  178. package/dist/telemetry/withSpan.d.ts +9 -0
  179. package/dist/telemetry/withSpan.js +34 -0
  180. package/dist/types/contextTypes.d.ts +10 -0
  181. package/dist/types/streamTypes.d.ts +14 -0
  182. package/dist/utils/conversationMemory.js +123 -84
  183. package/dist/utils/logger.d.ts +5 -0
  184. package/dist/utils/logger.js +50 -2
  185. package/dist/utils/messageBuilder.js +22 -42
  186. package/dist/utils/modelDetection.js +3 -3
  187. package/dist/utils/providerRetry.d.ts +41 -0
  188. package/dist/utils/providerRetry.js +113 -0
  189. package/dist/utils/retryability.d.ts +14 -0
  190. package/dist/utils/retryability.js +22 -0
  191. package/dist/utils/sanitizers/svg.js +4 -5
  192. package/dist/utils/tokenEstimation.d.ts +11 -1
  193. package/dist/utils/tokenEstimation.js +19 -4
  194. package/dist/utils/videoAnalysisProcessor.js +7 -3
  195. package/dist/workflow/config.d.ts +26 -26
  196. package/package.json +1 -1
@@ -4,40 +4,175 @@
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
  }
43
178
  //# sourceMappingURL=slidingWindowTruncator.js.map
@@ -29,8 +29,8 @@ export async function summarizeMessages(messages, config) {
29
29
  }
30
30
  const summaryMessage = {
31
31
  id: `summary-${randomUUID()}`,
32
- role: "system",
33
- content: `Previous conversation summary:\n\n${summaryText}`,
32
+ role: "user",
33
+ content: `[Previous conversation summary]:\n\n${summaryText}`,
34
34
  timestamp: new Date().toISOString(),
35
35
  metadata: {
36
36
  isSummary: true,