@juspay/neurolink 9.10.0 → 9.11.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.
- package/CHANGELOG.md +12 -0
- package/dist/adapters/video/videoAnalyzer.d.ts +3 -3
- package/dist/adapters/video/videoAnalyzer.js +39 -25
- package/dist/agent/directTools.d.ts +3 -3
- package/dist/cli/commands/config.d.ts +9 -9
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/constants/contextWindows.d.ts +6 -3
- package/dist/constants/contextWindows.js +30 -3
- package/dist/constants/index.d.ts +3 -3
- package/dist/constants/retry.d.ts +4 -4
- package/dist/constants/retry.js +1 -1
- package/dist/context/contextCompactor.d.ts +1 -1
- package/dist/context/contextCompactor.js +59 -1
- package/dist/context/summarizationEngine.d.ts +2 -2
- package/dist/context/summarizationEngine.js +44 -18
- package/dist/context/toolOutputLimits.d.ts +22 -13
- package/dist/context/toolOutputLimits.js +58 -64
- package/dist/core/baseProvider.d.ts +11 -2
- package/dist/core/baseProvider.js +30 -1
- package/dist/core/conversationMemoryManager.d.ts +13 -1
- package/dist/core/conversationMemoryManager.js +36 -5
- package/dist/core/modules/GenerationHandler.d.ts +6 -0
- package/dist/core/modules/GenerationHandler.js +192 -7
- package/dist/core/modules/MessageBuilder.js +42 -4
- package/dist/core/modules/TelemetryHandler.js +4 -1
- package/dist/core/redisConversationMemoryManager.d.ts +19 -3
- package/dist/core/redisConversationMemoryManager.js +253 -58
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/lib/adapters/video/videoAnalyzer.d.ts +3 -3
- package/dist/lib/adapters/video/videoAnalyzer.js +39 -25
- package/dist/lib/agent/directTools.d.ts +7 -7
- package/dist/lib/constants/contextWindows.d.ts +6 -3
- package/dist/lib/constants/contextWindows.js +30 -3
- package/dist/lib/constants/index.d.ts +3 -3
- package/dist/lib/constants/retry.d.ts +4 -4
- package/dist/lib/constants/retry.js +1 -1
- package/dist/lib/context/contextCompactor.d.ts +1 -1
- package/dist/lib/context/contextCompactor.js +59 -1
- package/dist/lib/context/summarizationEngine.d.ts +2 -2
- package/dist/lib/context/summarizationEngine.js +44 -18
- package/dist/lib/context/toolOutputLimits.d.ts +22 -13
- package/dist/lib/context/toolOutputLimits.js +58 -64
- package/dist/lib/core/baseProvider.d.ts +11 -2
- package/dist/lib/core/baseProvider.js +30 -1
- package/dist/lib/core/conversationMemoryManager.d.ts +13 -1
- package/dist/lib/core/conversationMemoryManager.js +36 -5
- package/dist/lib/core/modules/GenerationHandler.d.ts +6 -0
- package/dist/lib/core/modules/GenerationHandler.js +192 -7
- package/dist/lib/core/modules/MessageBuilder.js +42 -4
- package/dist/lib/core/modules/TelemetryHandler.js +4 -1
- package/dist/lib/core/redisConversationMemoryManager.d.ts +19 -3
- package/dist/lib/core/redisConversationMemoryManager.js +253 -58
- package/dist/lib/files/fileTools.d.ts +3 -3
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +3 -0
- package/dist/lib/mcp/externalServerManager.js +36 -1
- package/dist/lib/memory/memoryRetrievalTools.d.ts +166 -0
- package/dist/lib/memory/memoryRetrievalTools.js +145 -0
- package/dist/lib/neurolink.d.ts +35 -1
- package/dist/lib/neurolink.js +471 -16
- package/dist/lib/providers/amazonBedrock.d.ts +1 -1
- package/dist/lib/providers/amazonBedrock.js +78 -45
- package/dist/lib/providers/amazonSagemaker.d.ts +1 -1
- package/dist/lib/providers/amazonSagemaker.js +1 -1
- package/dist/lib/providers/anthropic.d.ts +1 -1
- package/dist/lib/providers/anthropic.js +7 -7
- package/dist/lib/providers/anthropicBaseProvider.d.ts +1 -1
- package/dist/lib/providers/anthropicBaseProvider.js +7 -6
- package/dist/lib/providers/azureOpenai.d.ts +1 -1
- package/dist/lib/providers/azureOpenai.js +1 -1
- package/dist/lib/providers/googleAiStudio.d.ts +1 -1
- package/dist/lib/providers/googleAiStudio.js +5 -5
- package/dist/lib/providers/googleVertex.d.ts +1 -1
- package/dist/lib/providers/googleVertex.js +74 -17
- package/dist/lib/providers/huggingFace.d.ts +1 -1
- package/dist/lib/providers/huggingFace.js +1 -1
- package/dist/lib/providers/litellm.d.ts +1 -1
- package/dist/lib/providers/litellm.js +18 -16
- package/dist/lib/providers/mistral.d.ts +1 -1
- package/dist/lib/providers/mistral.js +1 -1
- package/dist/lib/providers/ollama.d.ts +1 -1
- package/dist/lib/providers/ollama.js +8 -7
- package/dist/lib/providers/openAI.d.ts +1 -1
- package/dist/lib/providers/openAI.js +6 -6
- package/dist/lib/providers/openRouter.d.ts +1 -1
- package/dist/lib/providers/openRouter.js +6 -2
- package/dist/lib/providers/openaiCompatible.d.ts +1 -1
- package/dist/lib/providers/openaiCompatible.js +1 -1
- package/dist/lib/proxy/proxyFetch.js +291 -65
- package/dist/lib/server/utils/validation.d.ts +4 -4
- package/dist/lib/services/server/ai/observability/instrumentation.js +12 -3
- package/dist/lib/telemetry/telemetryService.d.ts +2 -1
- package/dist/lib/telemetry/telemetryService.js +8 -1
- package/dist/lib/types/contextTypes.d.ts +26 -2
- package/dist/lib/types/conversation.d.ts +72 -40
- package/dist/lib/types/conversationMemoryInterface.d.ts +5 -1
- package/dist/lib/types/generateTypes.d.ts +26 -0
- package/dist/lib/types/modelTypes.d.ts +2 -2
- package/dist/lib/types/multimodal.d.ts +2 -0
- package/dist/lib/types/observability.d.ts +10 -0
- package/dist/lib/types/sdkTypes.d.ts +1 -1
- package/dist/lib/utils/conversationMemory.d.ts +4 -3
- package/dist/lib/utils/conversationMemory.js +44 -6
- package/dist/lib/utils/errorHandling.d.ts +5 -0
- package/dist/lib/utils/errorHandling.js +7 -2
- package/dist/lib/utils/logger.d.ts +8 -0
- package/dist/lib/utils/logger.js +56 -1
- package/dist/lib/utils/messageBuilder.js +74 -4
- package/dist/lib/utils/redis.js +6 -1
- package/dist/lib/utils/tokenEstimation.d.ts +2 -2
- package/dist/lib/utils/tokenEstimation.js +16 -1
- package/dist/lib/utils/videoAnalysisProcessor.d.ts +2 -1
- package/dist/lib/utils/videoAnalysisProcessor.js +7 -2
- package/dist/lib/workflow/config.d.ts +110 -110
- package/dist/mcp/externalServerManager.js +36 -1
- package/dist/memory/memoryRetrievalTools.d.ts +166 -0
- package/dist/memory/memoryRetrievalTools.js +144 -0
- package/dist/neurolink.d.ts +35 -1
- package/dist/neurolink.js +471 -16
- package/dist/providers/amazonBedrock.d.ts +1 -1
- package/dist/providers/amazonBedrock.js +78 -45
- package/dist/providers/amazonSagemaker.d.ts +1 -1
- package/dist/providers/amazonSagemaker.js +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +7 -7
- package/dist/providers/anthropicBaseProvider.d.ts +1 -1
- package/dist/providers/anthropicBaseProvider.js +7 -6
- package/dist/providers/azureOpenai.d.ts +1 -1
- package/dist/providers/azureOpenai.js +1 -1
- package/dist/providers/googleAiStudio.d.ts +1 -1
- package/dist/providers/googleAiStudio.js +5 -5
- package/dist/providers/googleVertex.d.ts +1 -1
- package/dist/providers/googleVertex.js +74 -17
- package/dist/providers/huggingFace.d.ts +1 -1
- package/dist/providers/huggingFace.js +1 -1
- package/dist/providers/litellm.d.ts +1 -1
- package/dist/providers/litellm.js +18 -16
- package/dist/providers/mistral.d.ts +1 -1
- package/dist/providers/mistral.js +1 -1
- package/dist/providers/ollama.d.ts +1 -1
- package/dist/providers/ollama.js +8 -7
- package/dist/providers/openAI.d.ts +1 -1
- package/dist/providers/openAI.js +6 -6
- package/dist/providers/openRouter.d.ts +1 -1
- package/dist/providers/openRouter.js +6 -2
- package/dist/providers/openaiCompatible.d.ts +1 -1
- package/dist/providers/openaiCompatible.js +1 -1
- package/dist/proxy/proxyFetch.js +291 -65
- package/dist/services/server/ai/observability/instrumentation.js +12 -3
- package/dist/telemetry/telemetryService.d.ts +2 -1
- package/dist/telemetry/telemetryService.js +8 -1
- package/dist/types/contextTypes.d.ts +26 -2
- package/dist/types/conversation.d.ts +72 -40
- package/dist/types/conversationMemoryInterface.d.ts +5 -1
- package/dist/types/generateTypes.d.ts +26 -0
- package/dist/types/modelTypes.d.ts +10 -10
- package/dist/types/multimodal.d.ts +2 -0
- package/dist/types/observability.d.ts +10 -0
- package/dist/types/sdkTypes.d.ts +1 -1
- package/dist/utils/conversationMemory.d.ts +4 -3
- package/dist/utils/conversationMemory.js +44 -6
- package/dist/utils/errorHandling.d.ts +5 -0
- package/dist/utils/errorHandling.js +7 -2
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.js +56 -1
- package/dist/utils/messageBuilder.js +74 -4
- package/dist/utils/redis.js +6 -1
- package/dist/utils/tokenEstimation.d.ts +2 -2
- package/dist/utils/tokenEstimation.js +16 -1
- package/dist/utils/videoAnalysisProcessor.d.ts +2 -1
- package/dist/utils/videoAnalysisProcessor.js +7 -2
- package/dist/workflow/config.d.ts +12 -12
- package/package.json +1 -1
|
@@ -71,6 +71,14 @@ export type ConversationMemoryConfig = {
|
|
|
71
71
|
maxToolOutputBytes?: number;
|
|
72
72
|
/** Tool output max lines (default: 2000) */
|
|
73
73
|
maxToolOutputLines?: number;
|
|
74
|
+
/**
|
|
75
|
+
* When true, buildContextMessages() returns the head/tail preview instead of
|
|
76
|
+
* the full tool output for tool_result messages. Default: false (full output sent to LLM).
|
|
77
|
+
* When false (default), the AI receives the complete tool output in content.
|
|
78
|
+
* When true, the AI receives the truncated preview and can use the retrieve_context
|
|
79
|
+
* tool to access full output if needed.
|
|
80
|
+
*/
|
|
81
|
+
sendToolPreview?: boolean;
|
|
74
82
|
/** File read budget as fraction of remaining context (default: 0.60) */
|
|
75
83
|
fileReadBudgetPercent?: number;
|
|
76
84
|
};
|
|
@@ -167,6 +175,64 @@ export type StreamEventSequence = {
|
|
|
167
175
|
/** Event-specific data */
|
|
168
176
|
[key: string]: unknown;
|
|
169
177
|
};
|
|
178
|
+
/** Structured metadata for tool_result messages. */
|
|
179
|
+
export type ToolResultData = {
|
|
180
|
+
/** Whether the tool execution succeeded */
|
|
181
|
+
success?: boolean;
|
|
182
|
+
/** Expression that was evaluated (for calculation tools) */
|
|
183
|
+
expression?: string;
|
|
184
|
+
/**
|
|
185
|
+
* The tool execution result.
|
|
186
|
+
* @deprecated Read from ChatMessage.content instead. This field is dynamically
|
|
187
|
+
* populated from content for backward compatibility and will be removed in a future version.
|
|
188
|
+
*/
|
|
189
|
+
result?: unknown;
|
|
190
|
+
/** Result type hint */
|
|
191
|
+
type?: string;
|
|
192
|
+
/** Error message if execution failed */
|
|
193
|
+
error?: string;
|
|
194
|
+
};
|
|
195
|
+
/** Metadata associated with a ChatMessage. */
|
|
196
|
+
export type ChatMessageMetadata = {
|
|
197
|
+
/** Is this a summary message? */
|
|
198
|
+
isSummary?: boolean;
|
|
199
|
+
/** First message ID that this summary covers */
|
|
200
|
+
summarizesFrom?: string;
|
|
201
|
+
/** Last message ID that this summary covers */
|
|
202
|
+
summarizesTo?: string;
|
|
203
|
+
/** Was this message truncated due to token limits? */
|
|
204
|
+
truncated?: boolean;
|
|
205
|
+
/** Source of the message (e.g., provider name, user input) */
|
|
206
|
+
source?: string;
|
|
207
|
+
/** Language of the message content */
|
|
208
|
+
language?: string;
|
|
209
|
+
/** Confidence score for AI-generated content */
|
|
210
|
+
confidence?: number;
|
|
211
|
+
/**
|
|
212
|
+
* Numeric timestamp for internal tracking and efficient comparisons.
|
|
213
|
+
* Format: Unix epoch milliseconds (number).
|
|
214
|
+
* Complements the ISO string `ChatMessage.timestamp` field.
|
|
215
|
+
* Use this for sorting, filtering, and performance-critical operations.
|
|
216
|
+
*/
|
|
217
|
+
timestamp?: number;
|
|
218
|
+
/** Model used to generate this message */
|
|
219
|
+
modelUsed?: string;
|
|
220
|
+
/** Unique signature identifying thought/reasoning patterns */
|
|
221
|
+
thoughtSignature?: string;
|
|
222
|
+
/** Hash of the thinking/reasoning content for deduplication */
|
|
223
|
+
thoughtHash?: string;
|
|
224
|
+
/** Whether extended thinking was used for this message */
|
|
225
|
+
thinkingExpanded?: boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Head/tail preview of a large tool output.
|
|
228
|
+
* Only present on tool_result messages where the output exceeded truncation limits.
|
|
229
|
+
* When `sendToolPreview` is enabled in config, `buildContextMessages()` returns
|
|
230
|
+
* this value as the message content instead of the full output.
|
|
231
|
+
*/
|
|
232
|
+
toolOutputPreview?: string;
|
|
233
|
+
/** Original byte size of the full tool output before any truncation */
|
|
234
|
+
originalSize?: number;
|
|
235
|
+
};
|
|
170
236
|
/**
|
|
171
237
|
* Chat message format for conversation history
|
|
172
238
|
*/
|
|
@@ -188,14 +254,8 @@ export type ChatMessage = {
|
|
|
188
254
|
tool?: string;
|
|
189
255
|
/** Tool arguments (optional) - for tool_call messages */
|
|
190
256
|
args?: Record<string, unknown>;
|
|
191
|
-
/** Tool result (optional) - for tool_result messages */
|
|
192
|
-
result?:
|
|
193
|
-
success?: boolean;
|
|
194
|
-
expression?: string;
|
|
195
|
-
result?: unknown;
|
|
196
|
-
type?: string;
|
|
197
|
-
error?: string;
|
|
198
|
-
};
|
|
257
|
+
/** Tool result metadata (optional) - for tool_result messages */
|
|
258
|
+
result?: ToolResultData;
|
|
199
259
|
/**
|
|
200
260
|
* Event sequence for rich history reconstruction
|
|
201
261
|
* Stores ordered events (text-chunk, ui-component, tool calls, HITL, etc.)
|
|
@@ -203,38 +263,8 @@ export type ChatMessage = {
|
|
|
203
263
|
* @since 8.21.0
|
|
204
264
|
*/
|
|
205
265
|
events?: StreamEventSequence[];
|
|
206
|
-
/** Message metadata
|
|
207
|
-
metadata?:
|
|
208
|
-
/** Is this a summary message? */
|
|
209
|
-
isSummary?: boolean;
|
|
210
|
-
/** First message ID that this summary covers */
|
|
211
|
-
summarizesFrom?: string;
|
|
212
|
-
/** Last message ID that this summary covers */
|
|
213
|
-
summarizesTo?: string;
|
|
214
|
-
/** Was this message truncated due to token limits? */
|
|
215
|
-
truncated?: boolean;
|
|
216
|
-
/** Source of the message (e.g., provider name, user input) */
|
|
217
|
-
source?: string;
|
|
218
|
-
/** Language of the message content */
|
|
219
|
-
language?: string;
|
|
220
|
-
/** Confidence score for AI-generated content */
|
|
221
|
-
confidence?: number;
|
|
222
|
-
/**
|
|
223
|
-
* Numeric timestamp for internal tracking and efficient comparisons.
|
|
224
|
-
* Format: Unix epoch milliseconds (number).
|
|
225
|
-
* Complements the ISO string `ChatMessage.timestamp` field.
|
|
226
|
-
* Use this for sorting, filtering, and performance-critical operations.
|
|
227
|
-
*/
|
|
228
|
-
timestamp?: number;
|
|
229
|
-
/** Model used to generate this message */
|
|
230
|
-
modelUsed?: string;
|
|
231
|
-
/** Unique signature identifying thought/reasoning patterns */
|
|
232
|
-
thoughtSignature?: string;
|
|
233
|
-
/** Hash of the thinking/reasoning content for deduplication */
|
|
234
|
-
thoughtHash?: string;
|
|
235
|
-
/** Whether extended thinking was used for this message */
|
|
236
|
-
thinkingExpanded?: boolean;
|
|
237
|
-
};
|
|
266
|
+
/** Message metadata */
|
|
267
|
+
metadata?: ChatMessageMetadata;
|
|
238
268
|
/** UUID identifying this condensation group */
|
|
239
269
|
condenseId?: string;
|
|
240
270
|
/** Points to summary that replaces this message */
|
|
@@ -323,6 +353,8 @@ export type StoreConversationTurnOptions = {
|
|
|
323
353
|
providerDetails?: ProviderDetails;
|
|
324
354
|
enableSummarization?: boolean;
|
|
325
355
|
events?: StreamEventSequence[];
|
|
356
|
+
/** Observability request identifier for log correlation */
|
|
357
|
+
requestId?: string;
|
|
326
358
|
/** API-reported token usage from provider response */
|
|
327
359
|
tokenUsage?: {
|
|
328
360
|
inputTokens?: number;
|
|
@@ -17,11 +17,15 @@ export type IConversationMemoryManager = {
|
|
|
17
17
|
/** Get session by ID */
|
|
18
18
|
getSession(sessionId: string, userId?: string): SessionMemory | undefined | Promise<SessionMemory | undefined>;
|
|
19
19
|
/** Build context messages for AI prompt injection */
|
|
20
|
-
buildContextMessages(sessionId: string, userId?: string, enableSummarization?: boolean): Promise<ChatMessage[]> | ChatMessage[];
|
|
20
|
+
buildContextMessages(sessionId: string, userId?: string, enableSummarization?: boolean, requestId?: string): Promise<ChatMessage[]> | ChatMessage[];
|
|
21
21
|
/** Clear a specific session */
|
|
22
22
|
clearSession(sessionId: string, userId?: string): Promise<boolean> | boolean;
|
|
23
23
|
/** Clear all sessions */
|
|
24
24
|
clearAllSessions(): Promise<void> | void;
|
|
25
25
|
/** Get memory statistics */
|
|
26
26
|
getStats(): Promise<ConversationMemoryStats> | ConversationMemoryStats;
|
|
27
|
+
/** Get raw messages array for a session (no context filtering or summarization) */
|
|
28
|
+
getSessionMessages(sessionId: string, userId?: string): Promise<ChatMessage[]>;
|
|
29
|
+
/** Replace the entire messages array for a session */
|
|
30
|
+
setSessionMessages(sessionId: string, messages: ChatMessage[], userId?: string): Promise<void>;
|
|
27
31
|
};
|
|
@@ -355,6 +355,26 @@ export type GenerateOptions = {
|
|
|
355
355
|
* ```
|
|
356
356
|
*/
|
|
357
357
|
rag?: RAGConfig;
|
|
358
|
+
/**
|
|
359
|
+
* Maximum budget in USD for this session. When the accumulated cost of all
|
|
360
|
+
* generate() calls on this NeuroLink instance exceeds this value, subsequent
|
|
361
|
+
* calls will throw a budget-exceeded error before making the API request.
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```typescript
|
|
365
|
+
* const result = await neurolink.generate({
|
|
366
|
+
* input: { text: "Summarize this" },
|
|
367
|
+
* maxBudgetUsd: 1.00
|
|
368
|
+
* });
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
maxBudgetUsd?: number;
|
|
372
|
+
/**
|
|
373
|
+
* Optional request identifier for observability and log correlation.
|
|
374
|
+
* When provided, this ID is forwarded to spans, logs, and telemetry so
|
|
375
|
+
* callers can correlate generation traces back to their own request lifecycle.
|
|
376
|
+
*/
|
|
377
|
+
requestId?: string;
|
|
358
378
|
/**
|
|
359
379
|
* File reference registry for on-demand file processing.
|
|
360
380
|
*
|
|
@@ -820,6 +840,12 @@ export type TextGenerationOptions = {
|
|
|
820
840
|
/** Thinking level (Gemini 3: minimal|low|medium|high). Ignored for Anthropic. */
|
|
821
841
|
thinkingLevel?: "minimal" | "low" | "medium" | "high";
|
|
822
842
|
};
|
|
843
|
+
/**
|
|
844
|
+
* Optional request identifier for observability and log correlation.
|
|
845
|
+
* When provided, this ID is forwarded to spans, logs, and telemetry so
|
|
846
|
+
* callers can correlate generation traces back to their own request lifecycle.
|
|
847
|
+
*/
|
|
848
|
+
requestId?: string;
|
|
823
849
|
};
|
|
824
850
|
/**
|
|
825
851
|
* Text generation result (consolidated from core types)
|
|
@@ -89,8 +89,8 @@ export declare const ModelConfigSchema: z.ZodObject<{
|
|
|
89
89
|
releaseDate: z.ZodString;
|
|
90
90
|
}, "strip", z.ZodTypeAny, {
|
|
91
91
|
id: string;
|
|
92
|
-
capabilities: string[];
|
|
93
92
|
displayName: string;
|
|
93
|
+
capabilities: string[];
|
|
94
94
|
deprecated: boolean;
|
|
95
95
|
pricing: {
|
|
96
96
|
input: number;
|
|
@@ -100,8 +100,8 @@ export declare const ModelConfigSchema: z.ZodObject<{
|
|
|
100
100
|
releaseDate: string;
|
|
101
101
|
}, {
|
|
102
102
|
id: string;
|
|
103
|
-
capabilities: string[];
|
|
104
103
|
displayName: string;
|
|
104
|
+
capabilities: string[];
|
|
105
105
|
deprecated: boolean;
|
|
106
106
|
pricing: {
|
|
107
107
|
input: number;
|
|
@@ -135,8 +135,8 @@ export declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
135
135
|
releaseDate: z.ZodString;
|
|
136
136
|
}, "strip", z.ZodTypeAny, {
|
|
137
137
|
id: string;
|
|
138
|
-
capabilities: string[];
|
|
139
138
|
displayName: string;
|
|
139
|
+
capabilities: string[];
|
|
140
140
|
deprecated: boolean;
|
|
141
141
|
pricing: {
|
|
142
142
|
input: number;
|
|
@@ -146,8 +146,8 @@ export declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
146
146
|
releaseDate: string;
|
|
147
147
|
}, {
|
|
148
148
|
id: string;
|
|
149
|
-
capabilities: string[];
|
|
150
149
|
displayName: string;
|
|
150
|
+
capabilities: string[];
|
|
151
151
|
deprecated: boolean;
|
|
152
152
|
pricing: {
|
|
153
153
|
input: number;
|
|
@@ -159,10 +159,12 @@ export declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
159
159
|
aliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
160
160
|
defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
161
161
|
}, "strip", z.ZodTypeAny, {
|
|
162
|
+
version: string;
|
|
163
|
+
lastUpdated: string;
|
|
162
164
|
models: Record<string, Record<string, {
|
|
163
165
|
id: string;
|
|
164
|
-
capabilities: string[];
|
|
165
166
|
displayName: string;
|
|
167
|
+
capabilities: string[];
|
|
166
168
|
deprecated: boolean;
|
|
167
169
|
pricing: {
|
|
168
170
|
input: number;
|
|
@@ -171,15 +173,15 @@ export declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
171
173
|
contextWindow: number;
|
|
172
174
|
releaseDate: string;
|
|
173
175
|
}>>;
|
|
174
|
-
version: string;
|
|
175
|
-
lastUpdated: string;
|
|
176
176
|
aliases?: Record<string, string> | undefined;
|
|
177
177
|
defaults?: Record<string, string> | undefined;
|
|
178
178
|
}, {
|
|
179
|
+
version: string;
|
|
180
|
+
lastUpdated: string;
|
|
179
181
|
models: Record<string, Record<string, {
|
|
180
182
|
id: string;
|
|
181
|
-
capabilities: string[];
|
|
182
183
|
displayName: string;
|
|
184
|
+
capabilities: string[];
|
|
183
185
|
deprecated: boolean;
|
|
184
186
|
pricing: {
|
|
185
187
|
input: number;
|
|
@@ -188,8 +190,6 @@ export declare const ModelRegistrySchema: z.ZodObject<{
|
|
|
188
190
|
contextWindow: number;
|
|
189
191
|
releaseDate: string;
|
|
190
192
|
}>>;
|
|
191
|
-
version: string;
|
|
192
|
-
lastUpdated: string;
|
|
193
193
|
aliases?: Record<string, string> | undefined;
|
|
194
194
|
defaults?: Record<string, string> | undefined;
|
|
195
195
|
}>;
|
|
@@ -316,6 +316,8 @@ export type MultimodalChatMessage = {
|
|
|
316
316
|
role: "user" | "assistant" | "system";
|
|
317
317
|
/** Content of the message - can be text or multimodal content array */
|
|
318
318
|
content: string | MessageContent[];
|
|
319
|
+
/** Provider-specific options (e.g. Anthropic cache_control) */
|
|
320
|
+
providerOptions?: Record<string, unknown>;
|
|
319
321
|
};
|
|
320
322
|
/**
|
|
321
323
|
* Multimodal message structure for provider adapters
|
|
@@ -97,6 +97,16 @@ export type LangfuseConfig = {
|
|
|
97
97
|
* @default false
|
|
98
98
|
*/
|
|
99
99
|
autoDetectExternalProvider?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* If true, NeuroLink will NOT register its own LangfuseSpanProcessor with the
|
|
102
|
+
* global TracerProvider when using external provider mode. Only the ContextEnricher
|
|
103
|
+
* will be registered. Use this when the host application already registers a
|
|
104
|
+
* LangfuseSpanProcessor (e.g., via a DeferredSpanProcessor) to prevent duplicate
|
|
105
|
+
* trace exports to Langfuse.
|
|
106
|
+
*
|
|
107
|
+
* @default false
|
|
108
|
+
*/
|
|
109
|
+
skipLangfuseSpanProcessor?: boolean;
|
|
100
110
|
/**
|
|
101
111
|
* Enable auto-detection of operation names from span names.
|
|
102
112
|
*
|
package/dist/types/sdkTypes.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type { AnalyticsData, TokenUsage } from "./analytics.js";
|
|
|
13
13
|
export type { BaseCommandArgs, CommandResult, GenerateCommandArgs, GenerateResult as CLIGenerateResult, MCPCommandArgs, ModelsCommandArgs, StreamChunk, } from "./cli.js";
|
|
14
14
|
export type { ErrorInfo, FunctionParameters, JsonArray, JsonObject, JsonValue, ProcessResult, Result, TestFunction, TestResult, Unknown, UnknownArray, UnknownRecord, } from "./common.js";
|
|
15
15
|
export type { Content, ImageContent, MultimodalMessage, ProcessedImage, ProviderImageFormat, ProviderMultimodalPayload, TextContent, VisionCapability, } from "./content.js";
|
|
16
|
-
export type { ChatMessage, ConversationMemoryConfig, ConversationMemoryError, ConversationMemoryEvents, MessageContent, MultimodalChatMessage, RedisConversationObject, RedisStorageConfig, SessionIdentifier, SessionMemory, SessionMetadata, StoreConversationTurnOptions, } from "./conversation.js";
|
|
16
|
+
export type { ChatMessage, ChatMessageMetadata, ToolResultData, ConversationMemoryConfig, ConversationMemoryError, ConversationMemoryEvents, MessageContent, MultimodalChatMessage, RedisConversationObject, RedisStorageConfig, SessionIdentifier, SessionMemory, SessionMetadata, StoreConversationTurnOptions, } from "./conversation.js";
|
|
17
17
|
export type { DomainConfig, DomainConfigOptions, DomainEvaluationCriteria, DomainTemplate, DomainType, DomainValidationRule, } from "./domainTypes.js";
|
|
18
18
|
export type { EnhancedEvaluationResult, EvaluationContext, EvaluationCriteria, EvaluationData, EvaluationRequest, } from "./evaluation.js";
|
|
19
19
|
export type { ExternalMCPConfigValidation, ExternalMCPManagerConfig, ExternalMCPOperationResult, ExternalMCPServerEvents, ExternalMCPServerHealth, ExternalMCPServerInstance, ExternalMCPServerStatus, ExternalMCPToolContext, ExternalMCPToolInfo, ExternalMCPToolResult, } from "./externalMcp.js";
|
|
@@ -19,14 +19,14 @@ export declare function getConversationMessages(conversationMemory: Conversation
|
|
|
19
19
|
* Store conversation turn for future context
|
|
20
20
|
* Saves user messages and AI responses for conversation memory
|
|
21
21
|
*/
|
|
22
|
-
export declare function storeConversationTurn(conversationMemory: ConversationMemoryManager | RedisConversationMemoryManager | null | undefined, originalOptions: TextGenerationOptions, result: TextGenerationResult, startTimeStamp?: Date | undefined): Promise<void>;
|
|
22
|
+
export declare function storeConversationTurn(conversationMemory: ConversationMemoryManager | RedisConversationMemoryManager | null | undefined, originalOptions: TextGenerationOptions, result: TextGenerationResult, startTimeStamp?: Date | undefined, requestId?: string): Promise<void>;
|
|
23
23
|
/**
|
|
24
24
|
* Build context messages from pointer onwards (token-based memory)
|
|
25
25
|
* Returns summary message (if exists) + all messages after the summarized pointer
|
|
26
26
|
* @param session - Session memory with pointer
|
|
27
27
|
* @returns Context messages to send to LLM
|
|
28
28
|
*/
|
|
29
|
-
export declare function buildContextFromPointer(session: SessionMemory): ChatMessage[];
|
|
29
|
+
export declare function buildContextFromPointer(session: SessionMemory, requestId?: string): ChatMessage[];
|
|
30
30
|
/**
|
|
31
31
|
* Create summarization prompt from message history
|
|
32
32
|
* Used by both in-memory and Redis conversation managers
|
|
@@ -60,9 +60,10 @@ export declare function getEffectiveTokenThreshold(provider: string, model: stri
|
|
|
60
60
|
* @param config - Conversation memory configuration containing provider/model settings
|
|
61
61
|
* @param previousSummary - Optional previous summary to build upon
|
|
62
62
|
* @param logPrefix - Prefix for log messages (e.g., "[ConversationMemory]" or "[RedisConversationMemoryManager]")
|
|
63
|
+
* @param requestId - Optional request ID for request-scoped tracing
|
|
63
64
|
* @returns Summary text or null if generation fails
|
|
64
65
|
*/
|
|
65
|
-
export declare function generateSummary(messages: ChatMessage[], config: Partial<ConversationMemoryConfig>, logPrefix?: string, previousSummary?: string): Promise<string | null>;
|
|
66
|
+
export declare function generateSummary(messages: ChatMessage[], config: Partial<ConversationMemoryConfig>, logPrefix?: string, previousSummary?: string, requestId?: string): Promise<string | null>;
|
|
66
67
|
/**
|
|
67
68
|
* Check if Redis is available for conversation memory.
|
|
68
69
|
* Migrated from the deprecated conversationMemoryUtils.ts.
|
|
@@ -74,8 +74,9 @@ export async function getConversationMessages(conversationMemory, options) {
|
|
|
74
74
|
* Store conversation turn for future context
|
|
75
75
|
* Saves user messages and AI responses for conversation memory
|
|
76
76
|
*/
|
|
77
|
-
export async function storeConversationTurn(conversationMemory, originalOptions, result, startTimeStamp) {
|
|
77
|
+
export async function storeConversationTurn(conversationMemory, originalOptions, result, startTimeStamp, requestId) {
|
|
78
78
|
logger.debug("[conversationMemoryUtils] storeConversationTurn called", {
|
|
79
|
+
requestId,
|
|
79
80
|
hasMemory: !!conversationMemory,
|
|
80
81
|
memoryType: conversationMemory?.constructor?.name || "NONE",
|
|
81
82
|
hasContext: !!originalOptions.context,
|
|
@@ -90,6 +91,7 @@ export async function storeConversationTurn(conversationMemory, originalOptions,
|
|
|
90
91
|
const sessionId = context.sessionId;
|
|
91
92
|
const userId = typeof context.userId === "string" ? context.userId : undefined;
|
|
92
93
|
logger.debug("[conversationMemoryUtils] Extracted session details from context", {
|
|
94
|
+
requestId,
|
|
93
95
|
sessionId,
|
|
94
96
|
userId,
|
|
95
97
|
contextKeys: Object.keys(context),
|
|
@@ -135,6 +137,7 @@ export async function storeConversationTurn(conversationMemory, originalOptions,
|
|
|
135
137
|
startTimeStamp,
|
|
136
138
|
providerDetails,
|
|
137
139
|
enableSummarization: originalOptions.enableSummarization,
|
|
140
|
+
requestId,
|
|
138
141
|
tokenUsage: result.usage
|
|
139
142
|
? {
|
|
140
143
|
inputTokens: result.usage.input,
|
|
@@ -146,6 +149,7 @@ export async function storeConversationTurn(conversationMemory, originalOptions,
|
|
|
146
149
|
: undefined,
|
|
147
150
|
});
|
|
148
151
|
logger.debug("[conversationMemoryUtils] Conversation turn stored successfully", {
|
|
152
|
+
requestId,
|
|
149
153
|
sessionId,
|
|
150
154
|
userId,
|
|
151
155
|
memoryType: conversationMemory.constructor.name,
|
|
@@ -154,11 +158,14 @@ export async function storeConversationTurn(conversationMemory, originalOptions,
|
|
|
154
158
|
});
|
|
155
159
|
}
|
|
156
160
|
catch (error) {
|
|
161
|
+
const details = error?.details;
|
|
157
162
|
logger.warn("[conversationMemoryUtils] Failed to store conversation turn", {
|
|
158
163
|
sessionId,
|
|
159
164
|
userId,
|
|
160
165
|
memoryType: conversationMemory.constructor.name,
|
|
161
166
|
error: error instanceof Error ? error.message : String(error),
|
|
167
|
+
innerError: details?.error || "none",
|
|
168
|
+
errorCode: error?.code || "unknown",
|
|
162
169
|
stack: error instanceof Error ? error.stack : undefined,
|
|
163
170
|
});
|
|
164
171
|
}
|
|
@@ -169,8 +176,17 @@ export async function storeConversationTurn(conversationMemory, originalOptions,
|
|
|
169
176
|
* @param session - Session memory with pointer
|
|
170
177
|
* @returns Context messages to send to LLM
|
|
171
178
|
*/
|
|
172
|
-
export function buildContextFromPointer(session) {
|
|
179
|
+
export function buildContextFromPointer(session, requestId) {
|
|
173
180
|
if (!session.summarizedUpToMessageId || !session.summarizedMessage) {
|
|
181
|
+
// Log context built for LLM (no summary)
|
|
182
|
+
const totalChars = session.messages.reduce((sum, msg) => sum + msg.content.length, 0);
|
|
183
|
+
logger.info("[ConversationMemory] Context built for LLM", {
|
|
184
|
+
requestId,
|
|
185
|
+
sessionId: session.sessionId,
|
|
186
|
+
contextMessages: session.messages.length,
|
|
187
|
+
summaryPrepended: false,
|
|
188
|
+
estimatedTokens: Math.ceil(totalChars / 4),
|
|
189
|
+
});
|
|
174
190
|
return session.messages;
|
|
175
191
|
}
|
|
176
192
|
// find a better way to wirte this
|
|
@@ -181,6 +197,15 @@ export function buildContextFromPointer(session) {
|
|
|
181
197
|
pointer: session.summarizedUpToMessageId,
|
|
182
198
|
totalMessages: session.messages.length,
|
|
183
199
|
});
|
|
200
|
+
// Log context built for LLM (pointer not found fallback)
|
|
201
|
+
const totalChars = session.messages.reduce((sum, msg) => sum + msg.content.length, 0);
|
|
202
|
+
logger.info("[ConversationMemory] Context built for LLM", {
|
|
203
|
+
requestId,
|
|
204
|
+
sessionId: session.sessionId,
|
|
205
|
+
contextMessages: session.messages.length,
|
|
206
|
+
summaryPrepended: false,
|
|
207
|
+
estimatedTokens: Math.ceil(totalChars / 4),
|
|
208
|
+
});
|
|
184
209
|
return session.messages;
|
|
185
210
|
}
|
|
186
211
|
const messagesAfterPointer = session.messages.slice(pointerIndex + 1);
|
|
@@ -202,7 +227,17 @@ export function buildContextFromPointer(session) {
|
|
|
202
227
|
totalMessages: session.messages.length,
|
|
203
228
|
summaryLength: session.summarizedMessage.length,
|
|
204
229
|
});
|
|
205
|
-
|
|
230
|
+
const contextMessages = [summaryMessage, ...messagesAfterPointer];
|
|
231
|
+
// Log context built for LLM with structural metadata
|
|
232
|
+
const totalChars = contextMessages.reduce((sum, msg) => sum + msg.content.length, 0);
|
|
233
|
+
logger.info("[ConversationMemory] Context built for LLM", {
|
|
234
|
+
requestId,
|
|
235
|
+
sessionId: session.sessionId,
|
|
236
|
+
contextMessages: contextMessages.length,
|
|
237
|
+
summaryPrepended: true,
|
|
238
|
+
estimatedTokens: Math.ceil(totalChars / 4),
|
|
239
|
+
});
|
|
240
|
+
return contextMessages;
|
|
206
241
|
}
|
|
207
242
|
/**
|
|
208
243
|
* Create summarization prompt from message history
|
|
@@ -282,16 +317,19 @@ export function getEffectiveTokenThreshold(provider, model, envOverride, session
|
|
|
282
317
|
* @param config - Conversation memory configuration containing provider/model settings
|
|
283
318
|
* @param previousSummary - Optional previous summary to build upon
|
|
284
319
|
* @param logPrefix - Prefix for log messages (e.g., "[ConversationMemory]" or "[RedisConversationMemoryManager]")
|
|
320
|
+
* @param requestId - Optional request ID for request-scoped tracing
|
|
285
321
|
* @returns Summary text or null if generation fails
|
|
286
322
|
*/
|
|
287
|
-
export async function generateSummary(messages, config, logPrefix = "[ConversationMemory]", previousSummary) {
|
|
323
|
+
export async function generateSummary(messages, config, logPrefix = "[ConversationMemory]", previousSummary, requestId) {
|
|
288
324
|
const summarizationPrompt = createSummarizationPrompt(messages, previousSummary);
|
|
289
325
|
const summarizer = new NeuroLink({
|
|
290
326
|
conversationMemory: { enabled: false },
|
|
291
327
|
});
|
|
292
328
|
try {
|
|
293
329
|
if (!config.summarizationProvider || !config.summarizationModel) {
|
|
294
|
-
logger.error(`${logPrefix} Missing summarization provider
|
|
330
|
+
logger.error(`${logPrefix} Missing summarization provider`, {
|
|
331
|
+
requestId,
|
|
332
|
+
});
|
|
295
333
|
return null;
|
|
296
334
|
}
|
|
297
335
|
const summaryResult = await summarizer.generate({
|
|
@@ -303,7 +341,7 @@ export async function generateSummary(messages, config, logPrefix = "[Conversati
|
|
|
303
341
|
return summaryResult.content || null;
|
|
304
342
|
}
|
|
305
343
|
catch (error) {
|
|
306
|
-
logger.error(`${logPrefix} Error generating summary`, { error });
|
|
344
|
+
logger.error(`${logPrefix} Error generating summary`, { requestId, error });
|
|
307
345
|
return null;
|
|
308
346
|
}
|
|
309
347
|
}
|
|
@@ -247,6 +247,11 @@ export declare class CircuitBreaker {
|
|
|
247
247
|
/**
|
|
248
248
|
* Detect AbortError from any source (DOMException, plain Error, or message-based).
|
|
249
249
|
* Used to short-circuit retry/fallback loops when an abort signal fires.
|
|
250
|
+
*
|
|
251
|
+
* Uses `includes()` for message checks because provider error handlers
|
|
252
|
+
* (e.g., googleVertex.formatProviderError) wrap the original AbortError
|
|
253
|
+
* in a formatted error like "❌ Provider Error\n\nThis operation was aborted\n\n..."
|
|
254
|
+
* which destroys the exact message match.
|
|
250
255
|
*/
|
|
251
256
|
export declare function isAbortError(error: unknown): boolean;
|
|
252
257
|
/**
|
|
@@ -823,6 +823,11 @@ export class CircuitBreaker {
|
|
|
823
823
|
/**
|
|
824
824
|
* Detect AbortError from any source (DOMException, plain Error, or message-based).
|
|
825
825
|
* Used to short-circuit retry/fallback loops when an abort signal fires.
|
|
826
|
+
*
|
|
827
|
+
* Uses `includes()` for message checks because provider error handlers
|
|
828
|
+
* (e.g., googleVertex.formatProviderError) wrap the original AbortError
|
|
829
|
+
* in a formatted error like "❌ Provider Error\n\nThis operation was aborted\n\n..."
|
|
830
|
+
* which destroys the exact message match.
|
|
826
831
|
*/
|
|
827
832
|
export function isAbortError(error) {
|
|
828
833
|
if (error instanceof DOMException && error.name === "AbortError") {
|
|
@@ -832,8 +837,8 @@ export function isAbortError(error) {
|
|
|
832
837
|
return true;
|
|
833
838
|
}
|
|
834
839
|
if (error instanceof Error &&
|
|
835
|
-
(error.message
|
|
836
|
-
error.message
|
|
840
|
+
(error.message?.includes("This operation was aborted") ||
|
|
841
|
+
error.message?.includes("The operation was aborted") ||
|
|
837
842
|
error.message?.includes("The user aborted a request"))) {
|
|
838
843
|
return true;
|
|
839
844
|
}
|
package/dist/utils/logger.d.ts
CHANGED
|
@@ -63,8 +63,15 @@ 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
|
+
* Safely serialize data to fully expanded JSON string.
|
|
68
|
+
* Handles circular references and non-serializable values.
|
|
69
|
+
* Zero truncation — all nested objects and arrays are fully expanded.
|
|
70
|
+
*/
|
|
71
|
+
private serializeData;
|
|
66
72
|
/**
|
|
67
73
|
* Outputs a log entry to the console based on the log level.
|
|
74
|
+
* Data is fully serialized to JSON — no [Object] or [Array] truncation.
|
|
68
75
|
*
|
|
69
76
|
* @param level - The log level (debug, info, warn, error).
|
|
70
77
|
* @param prefix - The formatted log prefix.
|
|
@@ -189,6 +196,7 @@ export declare const logger: {
|
|
|
189
196
|
error: (...args: unknown[]) => void;
|
|
190
197
|
always: (...args: unknown[]) => void;
|
|
191
198
|
table: (data: unknown) => void;
|
|
199
|
+
shouldLog: (level: LogLevel) => boolean;
|
|
192
200
|
setLogLevel: (level: LogLevel) => void;
|
|
193
201
|
getLogs: (level?: LogLevel) => LogEntry[];
|
|
194
202
|
clearLogs: () => void;
|
package/dist/utils/logger.js
CHANGED
|
@@ -95,8 +95,61 @@ class NeuroLinkLogger {
|
|
|
95
95
|
getLogPrefix(timestamp, level) {
|
|
96
96
|
return `[${timestamp}] [NEUROLINK:${UPPERCASE_LOG_LEVELS[level]}]`;
|
|
97
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Safely serialize data to fully expanded JSON string.
|
|
100
|
+
* Handles circular references and non-serializable values.
|
|
101
|
+
* Zero truncation — all nested objects and arrays are fully expanded.
|
|
102
|
+
*/
|
|
103
|
+
serializeData(data) {
|
|
104
|
+
if (data === undefined || data === null) {
|
|
105
|
+
return String(data);
|
|
106
|
+
}
|
|
107
|
+
if (typeof data !== "object") {
|
|
108
|
+
return String(data);
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
return JSON.stringify(data, (_key, value) => {
|
|
112
|
+
if (value instanceof Error) {
|
|
113
|
+
return {
|
|
114
|
+
name: value.name,
|
|
115
|
+
message: value.message,
|
|
116
|
+
stack: value.stack,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return value;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Handle circular references using a stack-based approach
|
|
124
|
+
// to avoid false "[Circular]" on diamond (shared) references
|
|
125
|
+
const ancestors = [];
|
|
126
|
+
try {
|
|
127
|
+
return JSON.stringify(data, function (_key, value) {
|
|
128
|
+
if (value instanceof Error) {
|
|
129
|
+
return {
|
|
130
|
+
name: value.name,
|
|
131
|
+
message: value.message,
|
|
132
|
+
stack: value.stack,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (typeof value === "object" && value !== null) {
|
|
136
|
+
// Only flag actual circular (ancestor) references
|
|
137
|
+
if (ancestors.includes(value)) {
|
|
138
|
+
return "[Circular]";
|
|
139
|
+
}
|
|
140
|
+
ancestors.push(value);
|
|
141
|
+
}
|
|
142
|
+
return value;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return "[Unserializable Object]";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
98
150
|
/**
|
|
99
151
|
* Outputs a log entry to the console based on the log level.
|
|
152
|
+
* Data is fully serialized to JSON — no [Object] or [Array] truncation.
|
|
100
153
|
*
|
|
101
154
|
* @param level - The log level (debug, info, warn, error).
|
|
102
155
|
* @param prefix - The formatted log prefix.
|
|
@@ -111,7 +164,7 @@ class NeuroLinkLogger {
|
|
|
111
164
|
error: console.error,
|
|
112
165
|
}[level];
|
|
113
166
|
if (data !== undefined && data !== null) {
|
|
114
|
-
logMethod(prefix, message, data);
|
|
167
|
+
logMethod(prefix, message, this.serializeData(data));
|
|
115
168
|
}
|
|
116
169
|
else {
|
|
117
170
|
logMethod(prefix, message);
|
|
@@ -338,6 +391,8 @@ export const logger = {
|
|
|
338
391
|
table: (data) => {
|
|
339
392
|
neuroLinkLogger.table(data);
|
|
340
393
|
},
|
|
394
|
+
// Expose log-level check for gating expensive operations
|
|
395
|
+
shouldLog: (level) => neuroLinkLogger.shouldLog(level),
|
|
341
396
|
// Expose structured logging methods
|
|
342
397
|
setLogLevel: (level) => neuroLinkLogger.setLogLevel(level),
|
|
343
398
|
getLogs: (level) => neuroLinkLogger.getLogs(level),
|