@juspay/neurolink 9.14.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 (241) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +15 -15
  3. package/dist/adapters/video/videoAnalyzer.d.ts +1 -1
  4. package/dist/adapters/video/videoAnalyzer.js +10 -8
  5. package/dist/auth/anthropicOAuth.d.ts +377 -0
  6. package/dist/auth/anthropicOAuth.js +914 -0
  7. package/dist/auth/index.d.ts +20 -0
  8. package/dist/auth/index.js +29 -0
  9. package/dist/auth/tokenStore.d.ts +225 -0
  10. package/dist/auth/tokenStore.js +521 -0
  11. package/dist/cli/commands/auth.d.ts +50 -0
  12. package/dist/cli/commands/auth.js +1115 -0
  13. package/dist/cli/commands/setup-anthropic.js +1 -14
  14. package/dist/cli/commands/setup-azure.js +1 -12
  15. package/dist/cli/commands/setup-bedrock.js +1 -9
  16. package/dist/cli/commands/setup-google-ai.js +1 -12
  17. package/dist/cli/commands/setup-openai.js +1 -14
  18. package/dist/cli/commands/workflow.d.ts +27 -0
  19. package/dist/cli/commands/workflow.js +216 -0
  20. package/dist/cli/factories/authCommandFactory.d.ts +52 -0
  21. package/dist/cli/factories/authCommandFactory.js +146 -0
  22. package/dist/cli/factories/commandFactory.d.ts +6 -0
  23. package/dist/cli/factories/commandFactory.js +171 -22
  24. package/dist/cli/index.js +0 -1
  25. package/dist/cli/parser.js +14 -2
  26. package/dist/cli/utils/maskCredential.d.ts +11 -0
  27. package/dist/cli/utils/maskCredential.js +23 -0
  28. package/dist/constants/contextWindows.js +107 -16
  29. package/dist/constants/enums.d.ts +119 -15
  30. package/dist/constants/enums.js +182 -22
  31. package/dist/constants/index.d.ts +3 -1
  32. package/dist/constants/index.js +11 -1
  33. package/dist/context/budgetChecker.js +1 -1
  34. package/dist/context/contextCompactor.js +31 -4
  35. package/dist/context/emergencyTruncation.d.ts +21 -0
  36. package/dist/context/emergencyTruncation.js +88 -0
  37. package/dist/context/errorDetection.d.ts +16 -0
  38. package/dist/context/errorDetection.js +48 -1
  39. package/dist/context/errors.d.ts +19 -0
  40. package/dist/context/errors.js +21 -0
  41. package/dist/context/stages/slidingWindowTruncator.d.ts +6 -0
  42. package/dist/context/stages/slidingWindowTruncator.js +159 -24
  43. package/dist/core/baseProvider.js +306 -200
  44. package/dist/core/conversationMemoryManager.js +104 -61
  45. package/dist/core/evaluationProviders.js +16 -33
  46. package/dist/core/factory.js +237 -164
  47. package/dist/core/modules/GenerationHandler.js +175 -116
  48. package/dist/core/modules/MessageBuilder.js +222 -170
  49. package/dist/core/modules/StreamHandler.d.ts +1 -0
  50. package/dist/core/modules/StreamHandler.js +95 -27
  51. package/dist/core/modules/TelemetryHandler.d.ts +10 -1
  52. package/dist/core/modules/TelemetryHandler.js +25 -7
  53. package/dist/core/modules/ToolsManager.js +115 -191
  54. package/dist/core/redisConversationMemoryManager.js +418 -282
  55. package/dist/factories/providerRegistry.d.ts +5 -0
  56. package/dist/factories/providerRegistry.js +20 -2
  57. package/dist/index.d.ts +3 -3
  58. package/dist/index.js +4 -2
  59. package/dist/lib/adapters/video/videoAnalyzer.d.ts +1 -1
  60. package/dist/lib/adapters/video/videoAnalyzer.js +10 -8
  61. package/dist/lib/auth/anthropicOAuth.d.ts +377 -0
  62. package/dist/lib/auth/anthropicOAuth.js +915 -0
  63. package/dist/lib/auth/index.d.ts +20 -0
  64. package/dist/lib/auth/index.js +30 -0
  65. package/dist/lib/auth/tokenStore.d.ts +225 -0
  66. package/dist/lib/auth/tokenStore.js +522 -0
  67. package/dist/lib/constants/contextWindows.js +107 -16
  68. package/dist/lib/constants/enums.d.ts +119 -15
  69. package/dist/lib/constants/enums.js +182 -22
  70. package/dist/lib/constants/index.d.ts +3 -1
  71. package/dist/lib/constants/index.js +11 -1
  72. package/dist/lib/context/budgetChecker.js +1 -1
  73. package/dist/lib/context/contextCompactor.js +31 -4
  74. package/dist/lib/context/emergencyTruncation.d.ts +21 -0
  75. package/dist/lib/context/emergencyTruncation.js +89 -0
  76. package/dist/lib/context/errorDetection.d.ts +16 -0
  77. package/dist/lib/context/errorDetection.js +48 -1
  78. package/dist/lib/context/errors.d.ts +19 -0
  79. package/dist/lib/context/errors.js +22 -0
  80. package/dist/lib/context/stages/slidingWindowTruncator.d.ts +6 -0
  81. package/dist/lib/context/stages/slidingWindowTruncator.js +159 -24
  82. package/dist/lib/core/baseProvider.js +306 -200
  83. package/dist/lib/core/conversationMemoryManager.js +104 -61
  84. package/dist/lib/core/evaluationProviders.js +16 -33
  85. package/dist/lib/core/factory.js +237 -164
  86. package/dist/lib/core/modules/GenerationHandler.js +175 -116
  87. package/dist/lib/core/modules/MessageBuilder.js +222 -170
  88. package/dist/lib/core/modules/StreamHandler.d.ts +1 -0
  89. package/dist/lib/core/modules/StreamHandler.js +95 -27
  90. package/dist/lib/core/modules/TelemetryHandler.d.ts +10 -1
  91. package/dist/lib/core/modules/TelemetryHandler.js +25 -7
  92. package/dist/lib/core/modules/ToolsManager.js +115 -191
  93. package/dist/lib/core/redisConversationMemoryManager.js +418 -282
  94. package/dist/lib/factories/providerRegistry.d.ts +5 -0
  95. package/dist/lib/factories/providerRegistry.js +20 -2
  96. package/dist/lib/index.d.ts +3 -3
  97. package/dist/lib/index.js +4 -2
  98. package/dist/lib/mcp/externalServerManager.js +66 -0
  99. package/dist/lib/mcp/mcpCircuitBreaker.js +24 -0
  100. package/dist/lib/mcp/mcpClientFactory.js +16 -0
  101. package/dist/lib/mcp/toolDiscoveryService.js +32 -6
  102. package/dist/lib/mcp/toolRegistry.js +193 -123
  103. package/dist/lib/models/anthropicModels.d.ts +267 -0
  104. package/dist/lib/models/anthropicModels.js +528 -0
  105. package/dist/lib/neurolink.d.ts +6 -0
  106. package/dist/lib/neurolink.js +1162 -646
  107. package/dist/lib/providers/amazonBedrock.d.ts +1 -1
  108. package/dist/lib/providers/amazonBedrock.js +521 -319
  109. package/dist/lib/providers/anthropic.d.ts +123 -2
  110. package/dist/lib/providers/anthropic.js +873 -27
  111. package/dist/lib/providers/anthropicBaseProvider.js +77 -17
  112. package/dist/lib/providers/googleAiStudio.d.ts +1 -1
  113. package/dist/lib/providers/googleAiStudio.js +292 -227
  114. package/dist/lib/providers/googleVertex.d.ts +36 -1
  115. package/dist/lib/providers/googleVertex.js +553 -260
  116. package/dist/lib/providers/ollama.js +329 -278
  117. package/dist/lib/providers/openAI.js +77 -19
  118. package/dist/lib/providers/sagemaker/parsers.js +3 -3
  119. package/dist/lib/providers/sagemaker/streaming.js +3 -3
  120. package/dist/lib/proxy/proxyFetch.js +81 -48
  121. package/dist/lib/rag/ChunkerFactory.js +1 -1
  122. package/dist/lib/rag/chunkers/MarkdownChunker.d.ts +22 -0
  123. package/dist/lib/rag/chunkers/MarkdownChunker.js +213 -9
  124. package/dist/lib/rag/chunking/markdownChunker.d.ts +16 -0
  125. package/dist/lib/rag/chunking/markdownChunker.js +174 -2
  126. package/dist/lib/rag/pipeline/contextAssembly.js +2 -1
  127. package/dist/lib/rag/ragIntegration.d.ts +18 -1
  128. package/dist/lib/rag/ragIntegration.js +94 -14
  129. package/dist/lib/rag/retrieval/vectorQueryTool.js +21 -4
  130. package/dist/lib/server/abstract/baseServerAdapter.js +4 -1
  131. package/dist/lib/server/adapters/fastifyAdapter.js +35 -30
  132. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +32 -0
  133. package/dist/lib/services/server/ai/observability/instrumentation.js +39 -0
  134. package/dist/lib/telemetry/attributes.d.ts +52 -0
  135. package/dist/lib/telemetry/attributes.js +61 -0
  136. package/dist/lib/telemetry/index.d.ts +3 -0
  137. package/dist/lib/telemetry/index.js +3 -0
  138. package/dist/lib/telemetry/telemetryService.d.ts +6 -0
  139. package/dist/lib/telemetry/telemetryService.js +6 -0
  140. package/dist/lib/telemetry/tracers.d.ts +15 -0
  141. package/dist/lib/telemetry/tracers.js +17 -0
  142. package/dist/lib/telemetry/withSpan.d.ts +9 -0
  143. package/dist/lib/telemetry/withSpan.js +35 -0
  144. package/dist/lib/types/contextTypes.d.ts +10 -0
  145. package/dist/lib/types/errors.d.ts +62 -0
  146. package/dist/lib/types/errors.js +107 -0
  147. package/dist/lib/types/index.d.ts +2 -1
  148. package/dist/lib/types/index.js +2 -0
  149. package/dist/lib/types/providers.d.ts +107 -0
  150. package/dist/lib/types/providers.js +69 -0
  151. package/dist/lib/types/streamTypes.d.ts +14 -0
  152. package/dist/lib/types/subscriptionTypes.d.ts +893 -0
  153. package/dist/lib/types/subscriptionTypes.js +8 -0
  154. package/dist/lib/utils/conversationMemory.js +121 -82
  155. package/dist/lib/utils/logger.d.ts +5 -0
  156. package/dist/lib/utils/logger.js +50 -2
  157. package/dist/lib/utils/messageBuilder.js +22 -42
  158. package/dist/lib/utils/modelDetection.js +3 -3
  159. package/dist/lib/utils/providerConfig.d.ts +167 -0
  160. package/dist/lib/utils/providerConfig.js +619 -9
  161. package/dist/lib/utils/providerRetry.d.ts +41 -0
  162. package/dist/lib/utils/providerRetry.js +114 -0
  163. package/dist/lib/utils/retryability.d.ts +14 -0
  164. package/dist/lib/utils/retryability.js +23 -0
  165. package/dist/lib/utils/sanitizers/svg.js +4 -5
  166. package/dist/lib/utils/tokenEstimation.d.ts +11 -1
  167. package/dist/lib/utils/tokenEstimation.js +19 -4
  168. package/dist/lib/utils/videoAnalysisProcessor.js +7 -3
  169. package/dist/mcp/externalServerManager.js +66 -0
  170. package/dist/mcp/mcpCircuitBreaker.js +24 -0
  171. package/dist/mcp/mcpClientFactory.js +16 -0
  172. package/dist/mcp/toolDiscoveryService.js +32 -6
  173. package/dist/mcp/toolRegistry.js +193 -123
  174. package/dist/models/anthropicModels.d.ts +267 -0
  175. package/dist/models/anthropicModels.js +527 -0
  176. package/dist/neurolink.d.ts +6 -0
  177. package/dist/neurolink.js +1162 -646
  178. package/dist/providers/amazonBedrock.d.ts +1 -1
  179. package/dist/providers/amazonBedrock.js +521 -319
  180. package/dist/providers/anthropic.d.ts +123 -2
  181. package/dist/providers/anthropic.js +873 -27
  182. package/dist/providers/anthropicBaseProvider.js +77 -17
  183. package/dist/providers/googleAiStudio.d.ts +1 -1
  184. package/dist/providers/googleAiStudio.js +292 -227
  185. package/dist/providers/googleVertex.d.ts +36 -1
  186. package/dist/providers/googleVertex.js +553 -260
  187. package/dist/providers/ollama.js +329 -278
  188. package/dist/providers/openAI.js +77 -19
  189. package/dist/providers/sagemaker/parsers.js +3 -3
  190. package/dist/providers/sagemaker/streaming.js +3 -3
  191. package/dist/proxy/proxyFetch.js +81 -48
  192. package/dist/rag/ChunkerFactory.js +1 -1
  193. package/dist/rag/chunkers/MarkdownChunker.d.ts +22 -0
  194. package/dist/rag/chunkers/MarkdownChunker.js +213 -9
  195. package/dist/rag/chunking/markdownChunker.d.ts +16 -0
  196. package/dist/rag/chunking/markdownChunker.js +174 -2
  197. package/dist/rag/pipeline/contextAssembly.js +2 -1
  198. package/dist/rag/ragIntegration.d.ts +18 -1
  199. package/dist/rag/ragIntegration.js +94 -14
  200. package/dist/rag/retrieval/vectorQueryTool.js +21 -4
  201. package/dist/server/abstract/baseServerAdapter.js +4 -1
  202. package/dist/server/adapters/fastifyAdapter.js +35 -30
  203. package/dist/services/server/ai/observability/instrumentation.d.ts +32 -0
  204. package/dist/services/server/ai/observability/instrumentation.js +39 -0
  205. package/dist/telemetry/attributes.d.ts +52 -0
  206. package/dist/telemetry/attributes.js +60 -0
  207. package/dist/telemetry/index.d.ts +3 -0
  208. package/dist/telemetry/index.js +3 -0
  209. package/dist/telemetry/telemetryService.d.ts +6 -0
  210. package/dist/telemetry/telemetryService.js +6 -0
  211. package/dist/telemetry/tracers.d.ts +15 -0
  212. package/dist/telemetry/tracers.js +16 -0
  213. package/dist/telemetry/withSpan.d.ts +9 -0
  214. package/dist/telemetry/withSpan.js +34 -0
  215. package/dist/types/contextTypes.d.ts +10 -0
  216. package/dist/types/errors.d.ts +62 -0
  217. package/dist/types/errors.js +107 -0
  218. package/dist/types/index.d.ts +2 -1
  219. package/dist/types/index.js +2 -0
  220. package/dist/types/providers.d.ts +107 -0
  221. package/dist/types/providers.js +69 -0
  222. package/dist/types/streamTypes.d.ts +14 -0
  223. package/dist/types/subscriptionTypes.d.ts +893 -0
  224. package/dist/types/subscriptionTypes.js +7 -0
  225. package/dist/utils/conversationMemory.js +121 -82
  226. package/dist/utils/logger.d.ts +5 -0
  227. package/dist/utils/logger.js +50 -2
  228. package/dist/utils/messageBuilder.js +22 -42
  229. package/dist/utils/modelDetection.js +3 -3
  230. package/dist/utils/providerConfig.d.ts +167 -0
  231. package/dist/utils/providerConfig.js +619 -9
  232. package/dist/utils/providerRetry.d.ts +41 -0
  233. package/dist/utils/providerRetry.js +113 -0
  234. package/dist/utils/retryability.d.ts +14 -0
  235. package/dist/utils/retryability.js +22 -0
  236. package/dist/utils/sanitizers/svg.js +4 -5
  237. package/dist/utils/tokenEstimation.d.ts +11 -1
  238. package/dist/utils/tokenEstimation.js +19 -4
  239. package/dist/utils/videoAnalysisProcessor.js +7 -3
  240. package/dist/workflow/config.d.ts +26 -26
  241. package/package.json +2 -1
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Claude Subscription Types for NeuroLink
3
+ *
4
+ * Type definitions for Claude subscription tiers, authentication methods,
5
+ * and usage tracking for Anthropic API access.
6
+ */
7
+ export {};
@@ -2,11 +2,16 @@
2
2
  * Conversation Memory Utilities
3
3
  * Handles configuration merging and conversation memory operations
4
4
  */
5
+ import { SpanKind, SpanStatusCode } from "@opentelemetry/api";
6
+ import { tracers } from "../telemetry/tracers.js";
7
+ import { withTimeout } from "./errorHandling.js";
5
8
  import { DEFAULT_FALLBACK_THRESHOLD, getConversationMemoryDefaults, MEMORY_THRESHOLD_PERCENTAGE, } from "../config/conversationMemory.js";
6
9
  import { getAvailableInputTokens } from "../constants/contextWindows.js";
7
10
  import { buildSummarizationPrompt } from "../context/prompts/summarizationPrompt.js";
8
- import { NeuroLink } from "../neurolink.js";
9
11
  import { logger } from "./logger.js";
12
+ const memoryTracer = tracers.memory;
13
+ // Cached NeuroLink instance for summarization to avoid creating a new instance per call
14
+ let cachedSummarizer = null;
10
15
  /**
11
16
  * Apply conversation memory defaults to user configuration
12
17
  * Merges user config with environment variables and default values
@@ -34,41 +39,49 @@ export async function getConversationMessages(conversationMemory, options) {
34
39
  });
35
40
  return [];
36
41
  }
37
- try {
38
- // Extract userId from context
39
- const userId = options.context?.userId;
40
- const enableSummarization = options.enableSummarization ?? undefined;
41
- const messages = await conversationMemory.buildContextMessages(sessionId, userId, enableSummarization);
42
- logger.debug("[conversationMemoryUtils] Conversation messages retrieved successfully", {
43
- sessionId,
44
- messageCount: messages.length,
45
- messageTypes: messages.map((m) => m.role),
46
- firstMessage: messages.length > 0
47
- ? {
48
- role: messages[0].role,
49
- contentLength: messages[0].content.length,
50
- contentPreview: messages[0].content.substring(0, 50),
51
- }
52
- : null,
53
- lastMessage: messages.length > 0
54
- ? {
55
- role: messages[messages.length - 1].role,
56
- contentLength: messages[messages.length - 1].content.length,
57
- contentPreview: messages[messages.length - 1].content.substring(0, 50),
58
- }
59
- : null,
60
- });
61
- return messages;
62
- }
63
- catch (error) {
64
- logger.warn("[conversationMemoryUtils] Failed to get conversation messages", {
65
- sessionId,
66
- memoryType: conversationMemory.constructor.name,
67
- error: error instanceof Error ? error.message : String(error),
68
- stack: error instanceof Error ? error.stack : undefined,
69
- });
70
- return [];
71
- }
42
+ return memoryTracer.startActiveSpan("neurolink.conversation.getMessages", {
43
+ kind: SpanKind.INTERNAL,
44
+ attributes: {
45
+ "session.id": sessionId,
46
+ "memory.type": conversationMemory.constructor.name,
47
+ },
48
+ }, async (span) => {
49
+ try {
50
+ // Extract userId from context
51
+ const userId = options.context?.userId;
52
+ if (userId) {
53
+ span.setAttribute("user.id", userId);
54
+ }
55
+ const enableSummarization = options.enableSummarization ?? undefined;
56
+ const messages = await conversationMemory.buildContextMessages(sessionId, userId, enableSummarization);
57
+ span.setAttribute("message.count", messages.length);
58
+ if (logger.shouldLog("debug")) {
59
+ logger.debug("[conversationMemoryUtils] Conversation messages retrieved successfully", {
60
+ sessionId,
61
+ messageCount: messages.length,
62
+ messageTypes: messages.map((m) => m.role),
63
+ });
64
+ }
65
+ return messages;
66
+ }
67
+ catch (error) {
68
+ span.setStatus({
69
+ code: SpanStatusCode.ERROR,
70
+ message: error instanceof Error ? error.message : String(error),
71
+ });
72
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
73
+ logger.warn("[conversationMemoryUtils] Failed to get conversation messages", {
74
+ sessionId,
75
+ memoryType: conversationMemory.constructor.name,
76
+ error: error instanceof Error ? error.message : String(error),
77
+ stack: error instanceof Error ? error.stack : undefined,
78
+ });
79
+ return [];
80
+ }
81
+ finally {
82
+ span.end();
83
+ }
84
+ });
72
85
  }
73
86
  /**
74
87
  * Store conversation turn for future context
@@ -128,47 +141,66 @@ export async function storeConversationTurn(conversationMemory, originalOptions,
128
141
  model: result.model,
129
142
  };
130
143
  }
131
- try {
132
- await conversationMemory.storeConversationTurn({
133
- sessionId,
134
- userId,
135
- userMessage,
136
- aiResponse,
137
- startTimeStamp,
138
- providerDetails,
139
- enableSummarization: originalOptions.enableSummarization,
140
- requestId,
141
- tokenUsage: result.usage
142
- ? {
143
- inputTokens: result.usage.input,
144
- outputTokens: result.usage.output,
145
- totalTokens: result.usage.total,
146
- cacheReadTokens: result.usage.cacheReadTokens,
147
- cacheWriteTokens: result.usage.cacheCreationTokens,
148
- }
149
- : undefined,
150
- });
151
- logger.debug("[conversationMemoryUtils] Conversation turn stored successfully", {
152
- requestId,
153
- sessionId,
154
- userId,
155
- memoryType: conversationMemory.constructor.name,
156
- userMessageLength: userMessage.length,
157
- aiResponseLength: aiResponse.length,
158
- });
159
- }
160
- catch (error) {
161
- const details = error?.details;
162
- logger.warn("[conversationMemoryUtils] Failed to store conversation turn", {
163
- sessionId,
164
- userId,
165
- memoryType: conversationMemory.constructor.name,
166
- error: error instanceof Error ? error.message : String(error),
167
- innerError: details?.error || "none",
168
- errorCode: error?.code || "unknown",
169
- stack: error instanceof Error ? error.stack : undefined,
170
- });
171
- }
144
+ await memoryTracer.startActiveSpan("neurolink.conversation.storeTurn", {
145
+ kind: SpanKind.INTERNAL,
146
+ attributes: {
147
+ "session.id": sessionId,
148
+ "content.length": userMessage.length + aiResponse.length,
149
+ },
150
+ }, async (span) => {
151
+ if (userId) {
152
+ span.setAttribute("user.id", userId);
153
+ }
154
+ try {
155
+ await conversationMemory.storeConversationTurn({
156
+ sessionId,
157
+ userId,
158
+ userMessage,
159
+ aiResponse,
160
+ startTimeStamp,
161
+ providerDetails,
162
+ enableSummarization: originalOptions.enableSummarization,
163
+ requestId,
164
+ tokenUsage: result.usage
165
+ ? {
166
+ inputTokens: result.usage.input,
167
+ outputTokens: result.usage.output,
168
+ totalTokens: result.usage.total,
169
+ cacheReadTokens: result.usage.cacheReadTokens,
170
+ cacheWriteTokens: result.usage.cacheCreationTokens,
171
+ }
172
+ : undefined,
173
+ });
174
+ logger.debug("[conversationMemoryUtils] Conversation turn stored successfully", {
175
+ requestId,
176
+ sessionId,
177
+ userId,
178
+ memoryType: conversationMemory.constructor.name,
179
+ userMessageLength: userMessage.length,
180
+ aiResponseLength: aiResponse.length,
181
+ });
182
+ }
183
+ catch (error) {
184
+ span.setStatus({
185
+ code: SpanStatusCode.ERROR,
186
+ message: error instanceof Error ? error.message : String(error),
187
+ });
188
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
189
+ const details = error?.details;
190
+ logger.warn("[conversationMemoryUtils] Failed to store conversation turn", {
191
+ sessionId,
192
+ userId,
193
+ memoryType: conversationMemory.constructor.name,
194
+ error: error instanceof Error ? error.message : String(error),
195
+ innerError: details?.error || "none",
196
+ errorCode: error?.code || "unknown",
197
+ stack: error instanceof Error ? error.stack : undefined,
198
+ });
199
+ }
200
+ finally {
201
+ span.end();
202
+ }
203
+ });
172
204
  }
173
205
  /**
174
206
  * Build context messages from pointer onwards (token-based memory)
@@ -322,22 +354,29 @@ export function getEffectiveTokenThreshold(provider, model, envOverride, session
322
354
  */
323
355
  export async function generateSummary(messages, config, logPrefix = "[ConversationMemory]", previousSummary, requestId) {
324
356
  const summarizationPrompt = createSummarizationPrompt(messages, previousSummary);
325
- const summarizer = new NeuroLink({
326
- conversationMemory: { enabled: false },
327
- });
357
+ const SUMMARIZER_INIT_TIMEOUT = 15_000;
358
+ const SUMMARIZER_GENERATE_TIMEOUT = 60_000;
328
359
  try {
360
+ if (!cachedSummarizer) {
361
+ cachedSummarizer = await withTimeout((async () => {
362
+ const { NeuroLink: NeuroLinkClass } = await import("../neurolink.js");
363
+ return new NeuroLinkClass({
364
+ conversationMemory: { enabled: false },
365
+ });
366
+ })(), SUMMARIZER_INIT_TIMEOUT, new Error("Summarizer initialization timed out"));
367
+ }
329
368
  if (!config.summarizationProvider || !config.summarizationModel) {
330
369
  logger.error(`${logPrefix} Missing summarization provider`, {
331
370
  requestId,
332
371
  });
333
372
  return null;
334
373
  }
335
- const summaryResult = await summarizer.generate({
374
+ const summaryResult = await withTimeout(cachedSummarizer.generate({
336
375
  input: { text: summarizationPrompt },
337
376
  provider: config.summarizationProvider,
338
377
  model: config.summarizationModel,
339
378
  disableTools: true,
340
- });
379
+ }), SUMMARIZER_GENERATE_TIMEOUT, new Error("Summary generation timed out"));
341
380
  return summaryResult.content || null;
342
381
  }
343
382
  catch (error) {
@@ -63,6 +63,11 @@ declare class NeuroLinkLogger {
63
63
  * @returns Formatted prefix string like "[2025-08-18T13:45:30.123Z] [NEUROLINK:ERROR]"
64
64
  */
65
65
  private getLogPrefix;
66
+ /**
67
+ * Extracts current OTel trace context (trace_id, span_id) if available.
68
+ * Returns empty object if OTel is not initialized or no active span exists.
69
+ */
70
+ private getTraceContext;
66
71
  /**
67
72
  * Safely serialize data to fully expanded JSON string.
68
73
  * Handles circular references and non-serializable values.
@@ -13,6 +13,22 @@
13
13
  * - Structured data support for complex objects
14
14
  * - Tabular data display
15
15
  */
16
+ // OTel trace context for log correlation (optional — gracefully no-ops if OTel not initialized)
17
+ let traceApi = null;
18
+ let traceApiPromise = null;
19
+ async function getTraceApi() {
20
+ if (!traceApiPromise) {
21
+ traceApiPromise = import("@opentelemetry/api")
22
+ .then((mod) => {
23
+ traceApi = mod;
24
+ return mod;
25
+ })
26
+ .catch(() => null);
27
+ }
28
+ return traceApiPromise;
29
+ }
30
+ // Eagerly kick off the import so the cached value is available for synchronous callers
31
+ void getTraceApi();
16
32
  // Pre-computed uppercase log levels for performance optimization
17
33
  const UPPERCASE_LOG_LEVELS = {
18
34
  debug: "DEBUG",
@@ -95,6 +111,34 @@ class NeuroLinkLogger {
95
111
  getLogPrefix(timestamp, level) {
96
112
  return `[${timestamp}] [NEUROLINK:${UPPERCASE_LOG_LEVELS[level]}]`;
97
113
  }
114
+ /**
115
+ * Extracts current OTel trace context (trace_id, span_id) if available.
116
+ * Returns empty object if OTel is not initialized or no active span exists.
117
+ */
118
+ getTraceContext() {
119
+ if (!traceApi) {
120
+ return {};
121
+ }
122
+ try {
123
+ const span = traceApi.trace.getSpan(traceApi.context.active());
124
+ if (!span) {
125
+ return {};
126
+ }
127
+ const spanContext = span.spanContext();
128
+ if (!spanContext ||
129
+ spanContext.traceId === "00000000000000000000000000000000") {
130
+ return {};
131
+ }
132
+ return {
133
+ trace_id: spanContext.traceId,
134
+ span_id: spanContext.spanId,
135
+ trace_flags: String(spanContext.traceFlags),
136
+ };
137
+ }
138
+ catch {
139
+ return {};
140
+ }
141
+ }
98
142
  /**
99
143
  * Safely serialize data to fully expanded JSON string.
100
144
  * Handles circular references and non-serializable values.
@@ -163,11 +207,15 @@ class NeuroLinkLogger {
163
207
  warn: console.warn,
164
208
  error: console.error,
165
209
  }[level];
210
+ const traceCtx = this.getTraceContext();
211
+ const tracePrefix = traceCtx.trace_id
212
+ ? ` [trace_id=${traceCtx.trace_id} span_id=${traceCtx.span_id}]`
213
+ : "";
166
214
  if (data !== undefined && data !== null) {
167
- logMethod(prefix, message, this.serializeData(data));
215
+ logMethod(prefix + tracePrefix, message, this.serializeData(data));
168
216
  }
169
217
  else {
170
- logMethod(prefix, message);
218
+ logMethod(prefix + tracePrefix, message);
171
219
  }
172
220
  }
173
221
  /**
@@ -436,56 +436,28 @@ function shouldUseStructuredOutput(options) {
436
436
  }
437
437
  /**
438
438
  * Log structural metadata about a composed message array without logging content.
439
- * Per-message breakdown is behind logger.debug() to avoid production spam.
439
+ * Only logs a compact summary (role counts, total chars, estimated tokens).
440
+ * Per-message breakdown is intentionally omitted to avoid log noise
441
+ * (~600 lines per retry cascade with many messages).
440
442
  */
441
443
  function logMessageComposition(messages, requestId) {
442
- // Skip entirely if neither info nor debug is enabled
443
- if (!logger.shouldLog("info")) {
444
+ if (!logger.shouldLog("debug")) {
444
445
  return;
445
446
  }
446
447
  const roles = {};
447
448
  let totalChars = 0;
448
449
  for (const msg of messages) {
449
- // Avoid JSON.stringify on multimodal content for the info-level summary;
450
- // accurate per-message breakdown (with sizes) is computed only when debug
451
- // logging is active (see below).
452
450
  const chars = typeof msg.content === "string" ? msg.content.length : 0;
453
451
  roles[msg.role] = (roles[msg.role] || 0) + 1;
454
452
  totalChars += chars;
455
453
  }
456
- logger.info("[MessageBuilder] Composed", {
454
+ logger.debug("[MessageBuilder] Composed", {
457
455
  requestId,
458
456
  totalMessages: messages.length,
459
457
  roles,
460
458
  totalChars,
461
459
  estimatedTokens: Math.ceil(totalChars / 4),
462
460
  });
463
- if (logger.shouldLog("debug")) {
464
- const breakdown = messages.map((msg, i) => {
465
- let chars;
466
- if (typeof msg.content === "string") {
467
- chars = msg.content.length;
468
- }
469
- else {
470
- try {
471
- chars = JSON.stringify(msg.content).length;
472
- }
473
- catch {
474
- chars = String(msg.content).length;
475
- }
476
- }
477
- return {
478
- index: i,
479
- role: msg.role,
480
- chars,
481
- estimatedTokens: Math.ceil(chars / 4),
482
- };
483
- });
484
- logger.debug("[MessageBuilder] Per-message breakdown", {
485
- requestId,
486
- breakdown,
487
- });
488
- }
489
461
  }
490
462
  /**
491
463
  * Build a properly formatted message array for AI providers
@@ -663,10 +635,11 @@ function enforceFileBudget(options, provider, model) {
663
635
  fileType: f.fileType,
664
636
  })), availableTokens);
665
637
  if (budgetResult.excluded.length > 0) {
666
- const includedNames = new Set(budgetResult.included.map((f) => f.name));
638
+ const includedIndices = new Set(budgetResult.included.map((f) => {
639
+ return budgetFiles.findIndex((bf) => bf.name === f.name);
640
+ }));
667
641
  options.input.files = options.input.files.filter((_file, idx) => {
668
- const entry = budgetFiles[idx];
669
- return includedNames.has(entry.name);
642
+ return includedIndices.has(idx);
670
643
  });
671
644
  options.input.text =
672
645
  (options.input.text || "") + "\n\n" + budgetResult.notices.join("\n");
@@ -1071,12 +1044,19 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1071
1044
  // Add conversation history if available
1072
1045
  const hasConversationHistory = options.conversationHistory && options.conversationHistory.length > 0;
1073
1046
  if (hasConversationHistory && options.conversationHistory) {
1074
- options.conversationHistory.forEach((msg) => {
1075
- messages.push({
1076
- role: msg.role,
1077
- content: msg.content,
1078
- });
1079
- });
1047
+ for (const msg of options.conversationHistory) {
1048
+ // Filter out tool_call and tool_result roles — only user/assistant/system are valid for AI providers
1049
+ if (msg.role === "user" ||
1050
+ msg.role === "assistant" ||
1051
+ msg.role === "system") {
1052
+ const providerOptions = msg.providerOptions;
1053
+ messages.push({
1054
+ role: msg.role,
1055
+ content: msg.content,
1056
+ ...(providerOptions && { providerOptions }),
1057
+ });
1058
+ }
1059
+ }
1080
1060
  }
1081
1061
  // Handle multimodal content
1082
1062
  try {
@@ -11,7 +11,7 @@ export function isGemini3Model(modelName) {
11
11
  if (!isValidModelName(modelName)) {
12
12
  return false;
13
13
  }
14
- return /^gemini-3(-.*)?$/i.test(modelName);
14
+ return /^gemini-3(\.\d+)?(-.*)?$/i.test(modelName);
15
15
  }
16
16
  export function isGemini25Model(modelName) {
17
17
  if (!isValidModelName(modelName)) {
@@ -46,10 +46,10 @@ export function getMaxThinkingBudgetTokens(modelName) {
46
46
  if (!isValidModelName(modelName)) {
47
47
  return 10000;
48
48
  }
49
- if (/^gemini-3-pro/i.test(modelName)) {
49
+ if (/^gemini-3(\.\d+)?-pro/i.test(modelName)) {
50
50
  return 100000;
51
51
  }
52
- if (/^gemini-3-flash/i.test(modelName)) {
52
+ if (/^gemini-3(\.\d+)?-flash/i.test(modelName)) {
53
53
  return 50000;
54
54
  }
55
55
  if (/^gemini-2\.5/i.test(modelName)) {
@@ -3,14 +3,22 @@
3
3
  * Consolidated configuration helpers for all AI providers
4
4
  * Eliminates duplicate error messages and configuration logic
5
5
  * Enhanced with format validation and advanced error classification
6
+ * Extended with Claude subscription OAuth support
6
7
  */
7
8
  import type { APIValidationResult } from "../types/utilities.js";
8
9
  import type { ProviderConfigOptions } from "../types/providers.js";
10
+ import type { AnthropicAuthMethod, ClaudeSubscriptionTier, AnthropicAuthConfig, AnthropicAuthConfigResult } from "../types/subscriptionTypes.js";
11
+ export type { AnthropicAuthMethod, ClaudeSubscriptionTier, AnthropicAuthConfig, OAuthToken, AnthropicAuthConfigResult, } from "../types/subscriptionTypes.js";
9
12
  /**
10
13
  * API key format validation patterns (extracted from advanced validation system)
11
14
  * Exported for use across the codebase to replace scattered regex patterns
12
15
  */
13
16
  export declare const API_KEY_FORMATS: Record<string, RegExp>;
17
+ /**
18
+ * OAuth token format validation patterns
19
+ * These patterns are more flexible as OAuth tokens can vary by provider
20
+ */
21
+ export declare const OAUTH_TOKEN_FORMATS: Record<string, RegExp>;
14
22
  /**
15
23
  * API key length constants to replace scattered magic numbers
16
24
  */
@@ -67,6 +75,7 @@ export declare function getProviderModel(envVar: string, defaultModel: string):
67
75
  export declare function hasProviderCredentials(envVars: string[]): boolean;
68
76
  /**
69
77
  * Creates Anthropic provider configuration
78
+ * Supports both API key and OAuth authentication methods
70
79
  */
71
80
  export declare function createAnthropicConfig(): ProviderConfigOptions;
72
81
  /**
@@ -126,3 +135,161 @@ export declare function getAWSSessionToken(): string | undefined;
126
135
  * Checks if HuggingFace credentials are available
127
136
  */
128
137
  export declare function hasHuggingFaceCredentials(): boolean;
138
+ /**
139
+ * Gets the configured Anthropic authentication method
140
+ * Defaults to "api_key" for backward compatibility
141
+ * @returns The configured authentication method
142
+ */
143
+ export declare function getAnthropicAuthMethod(): AnthropicAuthMethod;
144
+ /**
145
+ * Gets the configured Claude subscription tier
146
+ * Defaults to "api" for backward compatibility (API key users)
147
+ * @returns The configured subscription tier
148
+ */
149
+ export declare function getAnthropicSubscriptionTier(): ClaudeSubscriptionTier;
150
+ /**
151
+ * Validates OAuth access token format
152
+ * @param token The token to validate
153
+ * @returns True if the token format is valid
154
+ */
155
+ export declare function validateOAuthAccessToken(token: string): boolean;
156
+ /**
157
+ * Validates OAuth refresh token format
158
+ * @param token The token to validate
159
+ * @returns True if the token format is valid
160
+ */
161
+ export declare function validateOAuthRefreshToken(token: string): boolean;
162
+ /**
163
+ * Detects the best available authentication method for Anthropic
164
+ * Checks environment variables and returns the most appropriate auth configuration
165
+ * @returns Complete authentication configuration
166
+ */
167
+ export declare function detectAnthropicAuth(): AnthropicAuthConfigResult;
168
+ /**
169
+ * Checks if Anthropic credentials are available (either API key or OAuth)
170
+ * @returns True if any valid authentication is configured
171
+ */
172
+ export declare function hasAnthropicCredentials(): boolean;
173
+ /**
174
+ * Gets the authentication token or key for Anthropic API calls
175
+ * Returns the appropriate credential based on configured auth method
176
+ * @returns The API key or OAuth access token, or undefined if not configured
177
+ */
178
+ export declare function getAnthropicCredential(): string | undefined;
179
+ /**
180
+ * Checks if OAuth refresh is needed based on token state
181
+ * This is a placeholder for actual token expiration checking
182
+ * @returns True if refresh is needed
183
+ */
184
+ export declare function needsOAuthRefresh(): boolean;
185
+ /**
186
+ * Gets subscription tier limits for informational purposes
187
+ * These are approximate limits and may change
188
+ * @param tier The subscription tier
189
+ * @returns Object with tier limit information
190
+ */
191
+ export declare function getSubscriptionTierLimits(tier: ClaudeSubscriptionTier): {
192
+ messagesPerDay: number | "unlimited";
193
+ contextWindow: number;
194
+ priorityAccess: boolean;
195
+ description: string;
196
+ };
197
+ /**
198
+ * Environment variables for Anthropic/Claude subscription configuration
199
+ * These control authentication method, subscription tier, and feature flags
200
+ */
201
+ export declare const ANTHROPIC_ENV_VARS: {
202
+ /** Authentication method: "api_key" or "oauth" */
203
+ readonly AUTH_METHOD: "ANTHROPIC_AUTH_METHOD";
204
+ /** Subscription tier: "free", "pro", "max", "max_5", "max_20", or "api" */
205
+ readonly SUBSCRIPTION_TIER: "ANTHROPIC_SUBSCRIPTION_TIER";
206
+ /** Enable beta features: "true" or "false" */
207
+ readonly ENABLE_BETA_FEATURES: "ANTHROPIC_ENABLE_BETA_FEATURES";
208
+ /** API key for api_key authentication */
209
+ readonly API_KEY: "ANTHROPIC_API_KEY";
210
+ /** OAuth access token for oauth authentication (canonical, with BC fallbacks) */
211
+ readonly OAUTH_ACCESS_TOKEN: "ANTHROPIC_OAUTH_TOKEN";
212
+ /** OAuth refresh token for oauth authentication */
213
+ readonly OAUTH_REFRESH_TOKEN: "ANTHROPIC_OAUTH_REFRESH_TOKEN";
214
+ /** OAuth token expiry timestamp (Unix epoch in seconds) */
215
+ readonly OAUTH_TOKEN_EXPIRY: "ANTHROPIC_OAUTH_TOKEN_EXPIRY";
216
+ };
217
+ /**
218
+ * Valid subscription tier values for validation
219
+ */
220
+ export declare const VALID_SUBSCRIPTION_TIERS: readonly ClaudeSubscriptionTier[];
221
+ /**
222
+ * Valid authentication method values for validation
223
+ */
224
+ export declare const VALID_AUTH_METHODS: readonly AnthropicAuthMethod[];
225
+ /**
226
+ * Validates a subscription tier value
227
+ * @param tier The tier value to validate
228
+ * @returns True if the tier is valid, false otherwise
229
+ */
230
+ export declare function isValidSubscriptionTier(tier: string | undefined): tier is ClaudeSubscriptionTier;
231
+ /**
232
+ * Validates an authentication method value
233
+ * @param method The method value to validate
234
+ * @returns True if the method is valid, false otherwise
235
+ */
236
+ export declare function isValidAuthMethod(method: string | undefined): method is AnthropicAuthMethod;
237
+ /**
238
+ * Validates subscription tier and returns a detailed result
239
+ * @param tier The tier value to validate
240
+ * @returns Validation result with error details if invalid
241
+ */
242
+ export declare function validateSubscriptionTier(tier: string | undefined): {
243
+ isValid: boolean;
244
+ tier?: ClaudeSubscriptionTier;
245
+ error?: string;
246
+ };
247
+ /**
248
+ * Gets the complete Anthropic authentication configuration
249
+ * Detects auth method from environment or config and loads appropriate credentials
250
+ *
251
+ * @returns Complete AnthropicAuthConfig with method, credentials, and tier
252
+ */
253
+ export declare function getAnthropicAuthConfig(): AnthropicAuthConfig;
254
+ /**
255
+ * Detects the subscription tier from environment variables or config
256
+ * Checks environment variable first, then config, defaults to "api" if using API key
257
+ *
258
+ * @returns The detected subscription tier
259
+ */
260
+ export declare function detectSubscriptionTier(): ClaudeSubscriptionTier;
261
+ /**
262
+ * Determines whether beta features should be enabled
263
+ * Checks environment/config and defaults based on authentication method
264
+ *
265
+ * @returns True if beta features should be enabled
266
+ */
267
+ export declare function shouldEnableBetaFeatures(): boolean;
268
+ /**
269
+ * Gets complete subscription configuration including auth, tier, and features
270
+ * Combines all configuration sources into a unified config object
271
+ *
272
+ * @returns Complete subscription configuration
273
+ */
274
+ export declare function getAnthropicSubscriptionConfig(): {
275
+ auth: AnthropicAuthConfig;
276
+ tier: ClaudeSubscriptionTier;
277
+ betaFeaturesEnabled: boolean;
278
+ limits: ReturnType<typeof getSubscriptionTierLimits>;
279
+ isConfigured: boolean;
280
+ error?: string;
281
+ };
282
+ /**
283
+ * Checks if the current subscription tier has access to a specific feature
284
+ * @param feature The feature to check
285
+ * @param currentTier The current subscription tier (optional, auto-detects if not provided)
286
+ * @returns True if the tier has access to the feature
287
+ */
288
+ export declare function hasSubscriptionFeature(feature: "extended_thinking" | "priority_access" | "vision" | "file_analysis" | "mcp_tools" | "computer_use" | "web_search", currentTier?: ClaudeSubscriptionTier): boolean;
289
+ /**
290
+ * Gets a human-readable description of the current authentication configuration
291
+ * Useful for debugging and user feedback
292
+ *
293
+ * @returns Human-readable configuration description
294
+ */
295
+ export declare function describeAnthropicConfig(): string;