@juspay/neurolink 7.48.1 → 7.50.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 (153) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +215 -16
  3. package/dist/agent/directTools.d.ts +55 -0
  4. package/dist/agent/directTools.js +266 -0
  5. package/dist/cli/factories/commandFactory.d.ts +6 -0
  6. package/dist/cli/factories/commandFactory.js +149 -16
  7. package/dist/cli/index.js +13 -2
  8. package/dist/cli/loop/conversationSelector.d.ts +45 -0
  9. package/dist/cli/loop/conversationSelector.js +222 -0
  10. package/dist/cli/loop/optionsSchema.d.ts +1 -1
  11. package/dist/cli/loop/session.d.ts +36 -8
  12. package/dist/cli/loop/session.js +257 -61
  13. package/dist/core/baseProvider.d.ts +9 -0
  14. package/dist/core/baseProvider.js +45 -5
  15. package/dist/core/evaluation.js +5 -2
  16. package/dist/factories/providerRegistry.js +2 -2
  17. package/dist/index.d.ts +8 -2
  18. package/dist/index.js +11 -10
  19. package/dist/lib/agent/directTools.d.ts +55 -0
  20. package/dist/lib/agent/directTools.js +266 -0
  21. package/dist/lib/core/baseProvider.d.ts +9 -0
  22. package/dist/lib/core/baseProvider.js +45 -5
  23. package/dist/lib/core/evaluation.js +5 -2
  24. package/dist/lib/factories/providerRegistry.js +2 -2
  25. package/dist/lib/index.d.ts +8 -2
  26. package/dist/lib/index.js +11 -10
  27. package/dist/lib/mcp/factory.d.ts +2 -157
  28. package/dist/lib/mcp/flexibleToolValidator.d.ts +1 -5
  29. package/dist/lib/mcp/index.d.ts +3 -2
  30. package/dist/lib/mcp/mcpCircuitBreaker.d.ts +1 -75
  31. package/dist/lib/mcp/mcpClientFactory.d.ts +1 -20
  32. package/dist/lib/mcp/mcpClientFactory.js +1 -0
  33. package/dist/lib/mcp/registry.d.ts +3 -10
  34. package/dist/lib/mcp/servers/agent/directToolsServer.d.ts +1 -1
  35. package/dist/lib/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
  36. package/dist/lib/mcp/servers/utilities/utilityServer.d.ts +1 -1
  37. package/dist/lib/mcp/toolDiscoveryService.d.ts +3 -84
  38. package/dist/lib/mcp/toolRegistry.d.ts +2 -24
  39. package/dist/lib/middleware/builtin/guardrails.d.ts +5 -16
  40. package/dist/lib/middleware/builtin/guardrails.js +44 -39
  41. package/dist/lib/middleware/utils/guardrailsUtils.d.ts +64 -0
  42. package/dist/lib/middleware/utils/guardrailsUtils.js +387 -0
  43. package/dist/lib/neurolink.d.ts +36 -7
  44. package/dist/lib/neurolink.js +141 -0
  45. package/dist/lib/providers/anthropic.js +47 -3
  46. package/dist/lib/providers/azureOpenai.js +9 -2
  47. package/dist/lib/providers/googleAiStudio.js +9 -2
  48. package/dist/lib/providers/googleVertex.js +12 -2
  49. package/dist/lib/providers/huggingFace.js +1 -1
  50. package/dist/lib/providers/litellm.js +1 -1
  51. package/dist/lib/providers/mistral.js +1 -1
  52. package/dist/lib/providers/openAI.js +47 -3
  53. package/dist/lib/services/server/ai/observability/instrumentation.d.ts +57 -0
  54. package/dist/lib/services/server/ai/observability/instrumentation.js +170 -0
  55. package/dist/lib/session/globalSessionState.d.ts +26 -0
  56. package/dist/lib/session/globalSessionState.js +86 -1
  57. package/dist/lib/telemetry/index.d.ts +1 -0
  58. package/dist/lib/telemetry/telemetryService.d.ts +2 -0
  59. package/dist/lib/telemetry/telemetryService.js +7 -7
  60. package/dist/lib/types/cli.d.ts +28 -0
  61. package/dist/lib/types/content.d.ts +18 -5
  62. package/dist/lib/types/contextTypes.d.ts +1 -1
  63. package/dist/lib/types/conversation.d.ts +57 -4
  64. package/dist/lib/types/fileTypes.d.ts +65 -0
  65. package/dist/lib/types/fileTypes.js +4 -0
  66. package/dist/lib/types/generateTypes.d.ts +12 -0
  67. package/dist/lib/types/guardrails.d.ts +103 -0
  68. package/dist/lib/types/guardrails.js +1 -0
  69. package/dist/lib/types/index.d.ts +4 -2
  70. package/dist/lib/types/index.js +4 -0
  71. package/dist/lib/types/mcpTypes.d.ts +407 -14
  72. package/dist/lib/types/modelTypes.d.ts +6 -6
  73. package/dist/lib/types/observability.d.ts +49 -0
  74. package/dist/lib/types/observability.js +6 -0
  75. package/dist/lib/types/streamTypes.d.ts +7 -0
  76. package/dist/lib/types/tools.d.ts +132 -35
  77. package/dist/lib/utils/csvProcessor.d.ts +68 -0
  78. package/dist/lib/utils/csvProcessor.js +277 -0
  79. package/dist/lib/utils/fileDetector.d.ts +57 -0
  80. package/dist/lib/utils/fileDetector.js +457 -0
  81. package/dist/lib/utils/imageProcessor.d.ts +10 -0
  82. package/dist/lib/utils/imageProcessor.js +22 -0
  83. package/dist/lib/utils/loopUtils.d.ts +71 -0
  84. package/dist/lib/utils/loopUtils.js +262 -0
  85. package/dist/lib/utils/messageBuilder.d.ts +2 -1
  86. package/dist/lib/utils/messageBuilder.js +197 -2
  87. package/dist/lib/utils/optionsUtils.d.ts +1 -1
  88. package/dist/mcp/factory.d.ts +2 -157
  89. package/dist/mcp/flexibleToolValidator.d.ts +1 -5
  90. package/dist/mcp/index.d.ts +3 -2
  91. package/dist/mcp/mcpCircuitBreaker.d.ts +1 -75
  92. package/dist/mcp/mcpClientFactory.d.ts +1 -20
  93. package/dist/mcp/mcpClientFactory.js +1 -0
  94. package/dist/mcp/registry.d.ts +3 -10
  95. package/dist/mcp/servers/agent/directToolsServer.d.ts +1 -1
  96. package/dist/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
  97. package/dist/mcp/servers/utilities/utilityServer.d.ts +1 -1
  98. package/dist/mcp/toolDiscoveryService.d.ts +3 -84
  99. package/dist/mcp/toolRegistry.d.ts +2 -24
  100. package/dist/middleware/builtin/guardrails.d.ts +5 -16
  101. package/dist/middleware/builtin/guardrails.js +44 -39
  102. package/dist/middleware/utils/guardrailsUtils.d.ts +64 -0
  103. package/dist/middleware/utils/guardrailsUtils.js +387 -0
  104. package/dist/neurolink.d.ts +36 -7
  105. package/dist/neurolink.js +141 -0
  106. package/dist/providers/anthropic.js +47 -3
  107. package/dist/providers/azureOpenai.js +9 -2
  108. package/dist/providers/googleAiStudio.js +9 -2
  109. package/dist/providers/googleVertex.js +12 -2
  110. package/dist/providers/huggingFace.js +1 -1
  111. package/dist/providers/litellm.js +1 -1
  112. package/dist/providers/mistral.js +1 -1
  113. package/dist/providers/openAI.js +47 -3
  114. package/dist/services/server/ai/observability/instrumentation.d.ts +57 -0
  115. package/dist/services/server/ai/observability/instrumentation.js +170 -0
  116. package/dist/session/globalSessionState.d.ts +26 -0
  117. package/dist/session/globalSessionState.js +86 -1
  118. package/dist/telemetry/index.d.ts +1 -0
  119. package/dist/telemetry/telemetryService.d.ts +2 -0
  120. package/dist/telemetry/telemetryService.js +7 -7
  121. package/dist/types/cli.d.ts +28 -0
  122. package/dist/types/content.d.ts +18 -5
  123. package/dist/types/contextTypes.d.ts +1 -1
  124. package/dist/types/conversation.d.ts +57 -4
  125. package/dist/types/fileTypes.d.ts +65 -0
  126. package/dist/types/fileTypes.js +4 -0
  127. package/dist/types/generateTypes.d.ts +12 -0
  128. package/dist/types/guardrails.d.ts +103 -0
  129. package/dist/types/guardrails.js +1 -0
  130. package/dist/types/index.d.ts +4 -2
  131. package/dist/types/index.js +4 -0
  132. package/dist/types/mcpTypes.d.ts +407 -14
  133. package/dist/types/modelTypes.d.ts +6 -6
  134. package/dist/types/observability.d.ts +49 -0
  135. package/dist/types/observability.js +6 -0
  136. package/dist/types/streamTypes.d.ts +7 -0
  137. package/dist/types/tools.d.ts +132 -35
  138. package/dist/utils/csvProcessor.d.ts +68 -0
  139. package/dist/utils/csvProcessor.js +277 -0
  140. package/dist/utils/fileDetector.d.ts +57 -0
  141. package/dist/utils/fileDetector.js +457 -0
  142. package/dist/utils/imageProcessor.d.ts +10 -0
  143. package/dist/utils/imageProcessor.js +22 -0
  144. package/dist/utils/loopUtils.d.ts +71 -0
  145. package/dist/utils/loopUtils.js +262 -0
  146. package/dist/utils/messageBuilder.d.ts +2 -1
  147. package/dist/utils/messageBuilder.js +197 -2
  148. package/dist/utils/optionsUtils.d.ts +1 -1
  149. package/package.json +18 -16
  150. package/dist/lib/mcp/contracts/mcpContract.d.ts +0 -106
  151. package/dist/lib/mcp/contracts/mcpContract.js +0 -5
  152. package/dist/mcp/contracts/mcpContract.d.ts +0 -106
  153. package/dist/mcp/contracts/mcpContract.js +0 -5
@@ -0,0 +1,170 @@
1
+ /**
2
+ * OpenTelemetry Instrumentation for Langfuse v4
3
+ *
4
+ * Configures OpenTelemetry TracerProvider with LangfuseSpanProcessor to capture
5
+ * traces from Vercel AI SDK's experimental_telemetry feature.
6
+ *
7
+ * Flow: Vercel AI SDK → OpenTelemetry Spans → LangfuseSpanProcessor → Langfuse Platform
8
+ */
9
+ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
10
+ import { LangfuseSpanProcessor } from "@langfuse/otel";
11
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from "@opentelemetry/semantic-conventions";
12
+ import { resourceFromAttributes } from "@opentelemetry/resources";
13
+ import { logger } from "../../../../utils/logger.js";
14
+ const LOG_PREFIX = "[OpenTelemetry]";
15
+ let tracerProvider = null;
16
+ let langfuseProcessor = null;
17
+ let isInitialized = false;
18
+ let isCredentialsValid = false;
19
+ let currentConfig = null;
20
+ /**
21
+ * Initialize OpenTelemetry with Langfuse span processor
22
+ *
23
+ * This connects Vercel AI SDK's experimental_telemetry to Langfuse by:
24
+ * 1. Creating LangfuseSpanProcessor with Langfuse credentials
25
+ * 2. Creating a NodeTracerProvider with service metadata and span processor
26
+ * 3. Registering the provider globally for AI SDK to use
27
+ *
28
+ * @param config - Langfuse configuration passed from parent application
29
+ */
30
+ export function initializeOpenTelemetry(config) {
31
+ if (isInitialized) {
32
+ logger.debug(`${LOG_PREFIX} Already initialized`);
33
+ return;
34
+ }
35
+ if (!config.enabled) {
36
+ logger.debug(`${LOG_PREFIX} Langfuse disabled, skipping initialization`);
37
+ isInitialized = true;
38
+ return;
39
+ }
40
+ if (!config.publicKey || !config.secretKey) {
41
+ logger.warn(`${LOG_PREFIX} Langfuse enabled but missing credentials, skipping initialization`);
42
+ isInitialized = true;
43
+ isCredentialsValid = false;
44
+ return;
45
+ }
46
+ try {
47
+ currentConfig = config;
48
+ isCredentialsValid = true;
49
+ // Create Langfuse span processor with configuration
50
+ langfuseProcessor = new LangfuseSpanProcessor({
51
+ publicKey: config.publicKey,
52
+ secretKey: config.secretKey,
53
+ baseUrl: config.baseUrl || "https://cloud.langfuse.com",
54
+ environment: config.environment || "dev",
55
+ release: config.release || "v1.0.0",
56
+ });
57
+ // Create resource with service metadata (v2.x API)
58
+ const resource = resourceFromAttributes({
59
+ [ATTR_SERVICE_NAME]: "neurolink",
60
+ [ATTR_SERVICE_VERSION]: config.release || "v1.0.0",
61
+ "deployment.environment": config.environment || "dev",
62
+ });
63
+ // Initialize tracer provider with span processor and resource
64
+ tracerProvider = new NodeTracerProvider({
65
+ resource,
66
+ spanProcessors: [langfuseProcessor],
67
+ });
68
+ // Register provider globally so Vercel AI SDK can use it
69
+ tracerProvider.register();
70
+ isInitialized = true;
71
+ logger.info(`${LOG_PREFIX} Initialized with Langfuse span processor`, {
72
+ baseUrl: config.baseUrl || "https://cloud.langfuse.com",
73
+ environment: config.environment || "dev",
74
+ release: config.release || "v1.0.0",
75
+ });
76
+ }
77
+ catch (error) {
78
+ logger.error(`${LOG_PREFIX} Initialization failed`, {
79
+ error: error instanceof Error ? error.message : String(error),
80
+ stack: error instanceof Error ? error.stack : undefined,
81
+ });
82
+ throw error;
83
+ }
84
+ }
85
+ /**
86
+ * Flush all pending spans to Langfuse
87
+ */
88
+ export async function flushOpenTelemetry() {
89
+ if (!isInitialized) {
90
+ logger.debug(`${LOG_PREFIX} Not initialized, skipping flush`);
91
+ return;
92
+ }
93
+ if (!langfuseProcessor) {
94
+ logger.debug(`${LOG_PREFIX} No processor to flush (Langfuse disabled)`);
95
+ return;
96
+ }
97
+ try {
98
+ logger.info(`${LOG_PREFIX} Flushing pending spans to Langfuse...`);
99
+ await langfuseProcessor.forceFlush();
100
+ logger.info(`${LOG_PREFIX} Successfully flushed spans to Langfuse`);
101
+ }
102
+ catch (error) {
103
+ logger.error(`${LOG_PREFIX} Flush failed`, {
104
+ error: error instanceof Error ? error.message : String(error),
105
+ stack: error instanceof Error ? error.stack : undefined,
106
+ });
107
+ throw error;
108
+ }
109
+ }
110
+ /**
111
+ * Shutdown OpenTelemetry and Langfuse span processor
112
+ */
113
+ export async function shutdownOpenTelemetry() {
114
+ if (!isInitialized || !tracerProvider) {
115
+ return;
116
+ }
117
+ try {
118
+ await tracerProvider.shutdown();
119
+ tracerProvider = null;
120
+ langfuseProcessor = null;
121
+ isInitialized = false;
122
+ isCredentialsValid = false;
123
+ logger.debug(`${LOG_PREFIX} Shutdown complete`);
124
+ }
125
+ catch (error) {
126
+ logger.error(`${LOG_PREFIX} Shutdown failed`, {
127
+ error: error instanceof Error ? error.message : String(error),
128
+ });
129
+ }
130
+ }
131
+ /**
132
+ * Get the Langfuse span processor
133
+ */
134
+ export function getLangfuseSpanProcessor() {
135
+ return langfuseProcessor;
136
+ }
137
+ /**
138
+ * Get the tracer provider
139
+ */
140
+ export function getTracerProvider() {
141
+ return tracerProvider;
142
+ }
143
+ /**
144
+ * Check if OpenTelemetry is initialized
145
+ */
146
+ export function isOpenTelemetryInitialized() {
147
+ return isInitialized;
148
+ }
149
+ /**
150
+ * Get health status for Langfuse observability
151
+ */
152
+ export function getLangfuseHealthStatus() {
153
+ return {
154
+ isHealthy: currentConfig?.enabled &&
155
+ isInitialized &&
156
+ isCredentialsValid &&
157
+ langfuseProcessor !== null,
158
+ initialized: isInitialized,
159
+ credentialsValid: isCredentialsValid,
160
+ enabled: currentConfig?.enabled || false,
161
+ hasProcessor: langfuseProcessor !== null,
162
+ config: currentConfig
163
+ ? {
164
+ baseUrl: currentConfig.baseUrl || "https://cloud.langfuse.com",
165
+ environment: currentConfig.environment || "dev",
166
+ release: currentConfig.release || "v1.0.0",
167
+ }
168
+ : undefined,
169
+ };
170
+ }
@@ -13,6 +13,32 @@ export declare class GlobalSessionManager {
13
13
  private loopSession;
14
14
  static getInstance(): GlobalSessionManager;
15
15
  setLoopSession(config?: ConversationMemoryConfig): string;
16
+ /**
17
+ * Restore a loop session with an existing sessionId and NeuroLink instance
18
+ * Used for conversation restoration
19
+ */
20
+ restoreLoopSession(sessionId: string, neurolinkInstance: NeuroLink, config?: ConversationMemoryConfig, sessionVariables?: Record<string, SessionVariableValue>): void;
21
+ /**
22
+ * Update session variables during restoration
23
+ */
24
+ restoreSessionVariables(variables: Record<string, SessionVariableValue>): void;
25
+ /**
26
+ * Check if a session is currently active
27
+ */
28
+ hasActiveSession(): boolean;
29
+ /**
30
+ * Get current session metadata for restoration purposes
31
+ */
32
+ getSessionMetadata(): {
33
+ sessionId?: string;
34
+ conversationMemoryConfig?: ConversationMemoryConfig;
35
+ sessionVariables: Record<string, SessionVariableValue>;
36
+ isActive: boolean;
37
+ };
38
+ /**
39
+ * Update the sessionId of the current session (used during restoration)
40
+ */
41
+ updateSessionId(newSessionId: string): void;
16
42
  getLoopSession(): LoopSessionState | null;
17
43
  clearLoopSession(): void;
18
44
  getOrCreateNeuroLink(): NeuroLink;
@@ -1,5 +1,31 @@
1
1
  import { nanoid } from "nanoid";
2
2
  import { NeuroLink } from "../neurolink.js";
3
+ /**
4
+ * Build observability config from environment variables
5
+ * Used by CLI to configure NeuroLink instances
6
+ */
7
+ function buildObservabilityConfigFromEnv() {
8
+ const langfuseEnabled = process.env.LANGFUSE_ENABLED?.trim().toLowerCase() === "true";
9
+ const publicKey = process.env.LANGFUSE_PUBLIC_KEY?.trim();
10
+ const secretKey = process.env.LANGFUSE_SECRET_KEY?.trim();
11
+ if (!langfuseEnabled || !publicKey || !secretKey) {
12
+ return undefined;
13
+ }
14
+ return {
15
+ langfuse: {
16
+ enabled: langfuseEnabled,
17
+ publicKey,
18
+ secretKey,
19
+ baseUrl: process.env.LANGFUSE_BASE_URL?.trim() || "https://cloud.langfuse.com",
20
+ environment: process.env.LANGFUSE_ENVIRONMENT?.trim() ||
21
+ process.env.PUBLIC_APP_ENVIRONMENT?.trim() ||
22
+ "dev",
23
+ release: process.env.PUBLIC_APP_VERSION?.trim() ||
24
+ process.env.npm_package_version?.trim() ||
25
+ "v1.0.0",
26
+ },
27
+ };
28
+ }
3
29
  export class GlobalSessionManager {
4
30
  static instance;
5
31
  loopSession = null;
@@ -19,6 +45,11 @@ export class GlobalSessionManager {
19
45
  maxTurnsPerSession: config.maxTurnsPerSession,
20
46
  };
21
47
  }
48
+ // Add observability config from environment variables (CLI usage)
49
+ const observabilityConfig = buildObservabilityConfigFromEnv();
50
+ if (observabilityConfig) {
51
+ neurolinkOptions.observability = observabilityConfig;
52
+ }
22
53
  this.loopSession = {
23
54
  neurolinkInstance: new NeuroLink(neurolinkOptions),
24
55
  sessionId,
@@ -28,6 +59,55 @@ export class GlobalSessionManager {
28
59
  };
29
60
  return sessionId;
30
61
  }
62
+ /**
63
+ * Restore a loop session with an existing sessionId and NeuroLink instance
64
+ * Used for conversation restoration
65
+ */
66
+ restoreLoopSession(sessionId, neurolinkInstance, config, sessionVariables) {
67
+ this.loopSession = {
68
+ neurolinkInstance,
69
+ sessionId,
70
+ isActive: true,
71
+ conversationMemoryConfig: config,
72
+ sessionVariables: sessionVariables || {},
73
+ };
74
+ }
75
+ /**
76
+ * Update session variables during restoration
77
+ */
78
+ restoreSessionVariables(variables) {
79
+ const session = this.getLoopSession();
80
+ if (session) {
81
+ session.sessionVariables = { ...session.sessionVariables, ...variables };
82
+ }
83
+ }
84
+ /**
85
+ * Check if a session is currently active
86
+ */
87
+ hasActiveSession() {
88
+ return this.loopSession?.isActive ?? false;
89
+ }
90
+ /**
91
+ * Get current session metadata for restoration purposes
92
+ */
93
+ getSessionMetadata() {
94
+ const session = this.getLoopSession();
95
+ return {
96
+ sessionId: session?.sessionId,
97
+ conversationMemoryConfig: session?.conversationMemoryConfig,
98
+ sessionVariables: session?.sessionVariables || {},
99
+ isActive: session?.isActive ?? false,
100
+ };
101
+ }
102
+ /**
103
+ * Update the sessionId of the current session (used during restoration)
104
+ */
105
+ updateSessionId(newSessionId) {
106
+ const session = this.getLoopSession();
107
+ if (session) {
108
+ session.sessionId = newSessionId;
109
+ }
110
+ }
31
111
  getLoopSession() {
32
112
  return this.loopSession?.isActive ? this.loopSession : null;
33
113
  }
@@ -39,7 +119,12 @@ export class GlobalSessionManager {
39
119
  }
40
120
  getOrCreateNeuroLink() {
41
121
  const session = this.getLoopSession();
42
- return session ? session.neurolinkInstance : new NeuroLink();
122
+ if (session) {
123
+ return session.neurolinkInstance;
124
+ }
125
+ // Create new NeuroLink with observability config from environment (CLI usage)
126
+ const observabilityConfig = buildObservabilityConfigFromEnv();
127
+ return new NeuroLink(observabilityConfig ? { observability: observabilityConfig } : undefined);
43
128
  }
44
129
  getCurrentSessionId() {
45
130
  return this.getLoopSession()?.sessionId;
@@ -9,6 +9,7 @@ export declare function initializeTelemetry(): Promise<import("./telemetryServic
9
9
  */
10
10
  export declare function getTelemetryStatus(): Promise<{
11
11
  enabled: boolean;
12
+ initialized: boolean;
12
13
  endpoint?: string;
13
14
  service?: string;
14
15
  version?: string;
@@ -10,6 +10,7 @@ export declare class TelemetryService {
10
10
  private static instance;
11
11
  private sdk?;
12
12
  private enabled;
13
+ private initialized;
13
14
  private meter?;
14
15
  private tracer?;
15
16
  private aiRequestCounter?;
@@ -43,6 +44,7 @@ export declare class TelemetryService {
43
44
  isEnabled(): boolean;
44
45
  getStatus(): {
45
46
  enabled: boolean;
47
+ initialized: boolean;
46
48
  endpoint?: string;
47
49
  service?: string;
48
50
  version?: string;
@@ -1,14 +1,14 @@
1
1
  import { NodeSDK } from "@opentelemetry/sdk-node";
2
2
  import { metrics, trace, } from "@opentelemetry/api";
3
3
  import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
4
- import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
5
- import { Resource } from "@opentelemetry/resources";
4
+ import { resourceFromAttributes } from "@opentelemetry/resources";
6
5
  import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from "@opentelemetry/semantic-conventions";
7
6
  import { logger } from "../utils/logger.js";
8
7
  export class TelemetryService {
9
8
  static instance;
10
9
  sdk;
11
10
  enabled = false;
11
+ initialized = false;
12
12
  meter;
13
13
  tracer;
14
14
  // Optional Metrics (only created when enabled)
@@ -47,16 +47,12 @@ export class TelemetryService {
47
47
  }
48
48
  initializeTelemetry() {
49
49
  try {
50
- const resource = new Resource({
50
+ const resource = resourceFromAttributes({
51
51
  [ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME || "neurolink-ai",
52
52
  [ATTR_SERVICE_VERSION]: process.env.OTEL_SERVICE_VERSION || "3.0.1",
53
53
  });
54
54
  this.sdk = new NodeSDK({
55
55
  resource,
56
- traceExporter: new OTLPTraceExporter({
57
- url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||
58
- `${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces`,
59
- }),
60
56
  // Note: Metric reader configured separately
61
57
  instrumentations: [getNodeAutoInstrumentations()],
62
58
  });
@@ -102,11 +98,13 @@ export class TelemetryService {
102
98
  }
103
99
  try {
104
100
  await this.sdk?.start();
101
+ this.initialized = true;
105
102
  logger.debug("[Telemetry] SDK started successfully");
106
103
  }
107
104
  catch (error) {
108
105
  logger.error("[Telemetry] Failed to start SDK:", error);
109
106
  this.enabled = false;
107
+ this.initialized = false;
110
108
  }
111
109
  }
112
110
  // AI Operation Tracing (NO-OP when disabled)
@@ -250,6 +248,7 @@ export class TelemetryService {
250
248
  getStatus() {
251
249
  return {
252
250
  enabled: this.enabled,
251
+ initialized: this.initialized,
253
252
  endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
254
253
  service: process.env.OTEL_SERVICE_NAME || "neurolink-ai",
255
254
  version: process.env.OTEL_SERVICE_VERSION || "3.0.1",
@@ -285,6 +284,7 @@ export class TelemetryService {
285
284
  if (this.enabled && this.sdk) {
286
285
  try {
287
286
  await this.sdk.shutdown();
287
+ this.initialized = false;
288
288
  logger.debug("[Telemetry] SDK shutdown completed");
289
289
  }
290
290
  catch (error) {
@@ -411,6 +411,34 @@ export type JSONOutput = {
411
411
  export type ConsoleOverride = {
412
412
  [method: string]: (() => void) | undefined;
413
413
  };
414
+ /**
415
+ * Conversation choice for inquirer prompt
416
+ */
417
+ export type ConversationChoice = {
418
+ name: string;
419
+ value: string | "NEW_CONVERSATION";
420
+ short: string;
421
+ };
422
+ /**
423
+ * Session restore result
424
+ */
425
+ export type SessionRestoreResult = {
426
+ success: boolean;
427
+ sessionId: string;
428
+ messageCount: number;
429
+ error?: string;
430
+ lastActivity?: string;
431
+ };
432
+ /**
433
+ * Tool context for restored sessions
434
+ */
435
+ export type RestorationToolContext = Record<string, unknown> & {
436
+ sessionId: string;
437
+ userId: string;
438
+ source: string;
439
+ restored: boolean;
440
+ timestamp: string;
441
+ };
414
442
  /**
415
443
  * Type guard for generate result
416
444
  */
@@ -5,14 +5,14 @@
5
5
  /**
6
6
  * Text content type for multimodal messages
7
7
  */
8
- export interface TextContent {
8
+ export type TextContent = {
9
9
  type: "text";
10
10
  text: string;
11
- }
11
+ };
12
12
  /**
13
13
  * Image content type for multimodal messages
14
14
  */
15
- export interface ImageContent {
15
+ export type ImageContent = {
16
16
  type: "image";
17
17
  data: Buffer | string;
18
18
  mediaType?: "image/jpeg" | "image/png" | "image/gif" | "image/webp" | "image/bmp" | "image/tiff";
@@ -25,11 +25,24 @@ export interface ImageContent {
25
25
  };
26
26
  filename?: string;
27
27
  };
28
- }
28
+ };
29
+ /**
30
+ * CSV content type for multimodal messages
31
+ */
32
+ export type CSVContent = {
33
+ type: "csv";
34
+ data: Buffer | string;
35
+ metadata?: {
36
+ filename?: string;
37
+ maxRows?: number;
38
+ formatStyle?: "raw" | "markdown" | "json";
39
+ description?: string;
40
+ };
41
+ };
29
42
  /**
30
43
  * Union type for all content types
31
44
  */
32
- export type Content = TextContent | ImageContent;
45
+ export type Content = TextContent | ImageContent | CSVContent;
33
46
  /**
34
47
  * Vision capability information for providers
35
48
  */
@@ -3,6 +3,7 @@
3
3
  * Provides type-safe context integration for AI generation
4
4
  */
5
5
  import type { JsonObject } from "./common.js";
6
+ import type { ExecutionContext } from "../types/tools.js";
6
7
  /**
7
8
  * Base context interface for all AI operations
8
9
  */
@@ -149,7 +150,6 @@ export declare class ContextFactory {
149
150
  * Context conversion utilities for domain-specific data
150
151
  * Replaces hardcoded business context with generic domain context
151
152
  */
152
- import type { ExecutionContext } from "../mcp/contracts/mcpContract.js";
153
153
  interface ContextConversionOptions {
154
154
  preserveLegacyFields?: boolean;
155
155
  validateDomainData?: boolean;
@@ -148,6 +148,18 @@ export declare class ConversationMemoryError extends Error {
148
148
  details?: Record<string, unknown> | undefined;
149
149
  constructor(message: string, code: "STORAGE_ERROR" | "CONFIG_ERROR" | "SESSION_NOT_FOUND" | "CLEANUP_ERROR", details?: Record<string, unknown> | undefined);
150
150
  }
151
+ /**
152
+ * NeuroLink initialization options
153
+ * Configuration for creating NeuroLink instances with conversation memory
154
+ */
155
+ export interface NeurolinkOptions {
156
+ /** Conversation memory configuration */
157
+ conversationMemory?: ConversationMemoryConfig;
158
+ /** Session identifier for conversation context */
159
+ sessionId?: string;
160
+ /** Observability configuration */
161
+ observability?: import("./observability.js").ObservabilityConfig;
162
+ }
151
163
  /**
152
164
  * Session identifier for Redis storage operations
153
165
  */
@@ -166,10 +178,10 @@ export interface SessionMetadata {
166
178
  updatedAt: string;
167
179
  }
168
180
  /**
169
- * New Redis conversation storage object format
170
- * Contains conversation metadata and history in a single object
181
+ * Base conversation metadata (shared fields across all conversation types)
182
+ * Contains essential conversation information without heavy data arrays
171
183
  */
172
- export type RedisConversationObject = {
184
+ export interface ConversationBase {
173
185
  /** Unique conversation identifier (UUID v4) */
174
186
  id: string;
175
187
  /** Auto-generated conversation title */
@@ -182,9 +194,50 @@ export type RedisConversationObject = {
182
194
  createdAt: string;
183
195
  /** When this conversation was last updated */
184
196
  updatedAt: string;
197
+ }
198
+ /**
199
+ * Redis conversation storage object format
200
+ * Contains conversation metadata and full message history
201
+ */
202
+ export interface RedisConversationObject extends ConversationBase {
185
203
  /** Array of conversation messages */
186
204
  messages: ChatMessage[];
187
- };
205
+ }
206
+ /**
207
+ * Full conversation data for session restoration and manipulation
208
+ * Extends Redis storage object with additional loop mode metadata
209
+ */
210
+ export interface ConversationData extends RedisConversationObject {
211
+ /** Optional metadata for session variables and other loop mode data */
212
+ metadata?: {
213
+ /** Session variables set during loop mode */
214
+ sessionVariables?: Record<string, string | number | boolean>;
215
+ /** Message count (for compatibility) */
216
+ messageCount?: number;
217
+ /** Additional metadata can be added here */
218
+ [key: string]: unknown;
219
+ };
220
+ }
221
+ /**
222
+ * Conversation summary for listing and selection
223
+ * Contains conversation preview information without heavy message arrays
224
+ */
225
+ export interface ConversationSummary extends ConversationBase {
226
+ /** First message preview (for conversation preview) */
227
+ firstMessage: {
228
+ content: string;
229
+ timestamp: string;
230
+ };
231
+ /** Last message preview (for conversation preview) */
232
+ lastMessage: {
233
+ content: string;
234
+ timestamp: string;
235
+ };
236
+ /** Total number of messages in conversation */
237
+ messageCount: number;
238
+ /** Human-readable time since last update (e.g., "2 hours ago") */
239
+ duration: string;
240
+ }
188
241
  /**
189
242
  * Redis storage configuration
190
243
  */
@@ -0,0 +1,65 @@
1
+ /**
2
+ * File detection and processing types for unified file handling
3
+ */
4
+ /**
5
+ * Supported file types for multimodal input
6
+ */
7
+ export type FileType = "csv" | "image" | "pdf" | "text" | "unknown";
8
+ /**
9
+ * File input can be Buffer or string (path/URL/data URI)
10
+ */
11
+ export type FileInput = Buffer | string;
12
+ /**
13
+ * File source type for tracking input origin
14
+ */
15
+ export type FileSource = "url" | "path" | "buffer" | "datauri";
16
+ /**
17
+ * File detection result with confidence scoring
18
+ */
19
+ export type FileDetectionResult = {
20
+ type: FileType;
21
+ mimeType: string;
22
+ extension: string | null;
23
+ source: FileSource;
24
+ metadata: {
25
+ size?: number;
26
+ filename?: string;
27
+ confidence: number;
28
+ };
29
+ };
30
+ /**
31
+ * File processing result after detection and conversion
32
+ */
33
+ export type FileProcessingResult = {
34
+ type: FileType;
35
+ content: string | Buffer;
36
+ mimeType: string;
37
+ metadata: {
38
+ confidence: number;
39
+ size?: number;
40
+ filename?: string;
41
+ rowCount?: number;
42
+ columnCount?: number;
43
+ columnNames?: string[];
44
+ sampleData?: string;
45
+ hasEmptyColumns?: boolean;
46
+ };
47
+ };
48
+ /**
49
+ * CSV processor options
50
+ */
51
+ export type CSVProcessorOptions = {
52
+ maxRows?: number;
53
+ formatStyle?: "raw" | "markdown" | "json";
54
+ includeHeaders?: boolean;
55
+ };
56
+ /**
57
+ * File detector options
58
+ */
59
+ export type FileDetectorOptions = {
60
+ maxSize?: number;
61
+ timeout?: number;
62
+ allowedTypes?: FileType[];
63
+ csvOptions?: CSVProcessorOptions;
64
+ confidenceThreshold?: number;
65
+ };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * File detection and processing types for unified file handling
3
+ */
4
+ export {};
@@ -15,11 +15,18 @@ export type GenerateOptions = {
15
15
  input: {
16
16
  text: string;
17
17
  images?: Array<Buffer | string>;
18
+ csvFiles?: Array<Buffer | string>;
19
+ files?: Array<Buffer | string>;
18
20
  content?: Array<TextContent | ImageContent>;
19
21
  };
20
22
  output?: {
21
23
  format?: "text" | "structured" | "json";
22
24
  };
25
+ csvOptions?: {
26
+ maxRows?: number;
27
+ formatStyle?: "raw" | "markdown" | "json";
28
+ includeHeaders?: boolean;
29
+ };
23
30
  provider?: AIProviderName | string;
24
31
  model?: string;
25
32
  region?: string;
@@ -168,6 +175,11 @@ export type TextGenerationOptions = {
168
175
  middleware?: MiddlewareFactoryOptions;
169
176
  expectedOutcome?: string;
170
177
  evaluationCriteria?: string[];
178
+ csvOptions?: {
179
+ maxRows?: number;
180
+ formatStyle?: "raw" | "markdown" | "json";
181
+ includeHeaders?: boolean;
182
+ };
171
183
  };
172
184
  /**
173
185
  * Text generation result (consolidated from core types)