@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.
- package/CHANGELOG.md +19 -0
- package/README.md +215 -16
- package/dist/agent/directTools.d.ts +55 -0
- package/dist/agent/directTools.js +266 -0
- package/dist/cli/factories/commandFactory.d.ts +6 -0
- package/dist/cli/factories/commandFactory.js +149 -16
- package/dist/cli/index.js +13 -2
- package/dist/cli/loop/conversationSelector.d.ts +45 -0
- package/dist/cli/loop/conversationSelector.js +222 -0
- package/dist/cli/loop/optionsSchema.d.ts +1 -1
- package/dist/cli/loop/session.d.ts +36 -8
- package/dist/cli/loop/session.js +257 -61
- package/dist/core/baseProvider.d.ts +9 -0
- package/dist/core/baseProvider.js +45 -5
- package/dist/core/evaluation.js +5 -2
- package/dist/factories/providerRegistry.js +2 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +11 -10
- package/dist/lib/agent/directTools.d.ts +55 -0
- package/dist/lib/agent/directTools.js +266 -0
- package/dist/lib/core/baseProvider.d.ts +9 -0
- package/dist/lib/core/baseProvider.js +45 -5
- package/dist/lib/core/evaluation.js +5 -2
- package/dist/lib/factories/providerRegistry.js +2 -2
- package/dist/lib/index.d.ts +8 -2
- package/dist/lib/index.js +11 -10
- package/dist/lib/mcp/factory.d.ts +2 -157
- package/dist/lib/mcp/flexibleToolValidator.d.ts +1 -5
- package/dist/lib/mcp/index.d.ts +3 -2
- package/dist/lib/mcp/mcpCircuitBreaker.d.ts +1 -75
- package/dist/lib/mcp/mcpClientFactory.d.ts +1 -20
- package/dist/lib/mcp/mcpClientFactory.js +1 -0
- package/dist/lib/mcp/registry.d.ts +3 -10
- package/dist/lib/mcp/servers/agent/directToolsServer.d.ts +1 -1
- package/dist/lib/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
- package/dist/lib/mcp/servers/utilities/utilityServer.d.ts +1 -1
- package/dist/lib/mcp/toolDiscoveryService.d.ts +3 -84
- package/dist/lib/mcp/toolRegistry.d.ts +2 -24
- package/dist/lib/middleware/builtin/guardrails.d.ts +5 -16
- package/dist/lib/middleware/builtin/guardrails.js +44 -39
- package/dist/lib/middleware/utils/guardrailsUtils.d.ts +64 -0
- package/dist/lib/middleware/utils/guardrailsUtils.js +387 -0
- package/dist/lib/neurolink.d.ts +36 -7
- package/dist/lib/neurolink.js +141 -0
- package/dist/lib/providers/anthropic.js +47 -3
- package/dist/lib/providers/azureOpenai.js +9 -2
- package/dist/lib/providers/googleAiStudio.js +9 -2
- package/dist/lib/providers/googleVertex.js +12 -2
- package/dist/lib/providers/huggingFace.js +1 -1
- package/dist/lib/providers/litellm.js +1 -1
- package/dist/lib/providers/mistral.js +1 -1
- package/dist/lib/providers/openAI.js +47 -3
- package/dist/lib/services/server/ai/observability/instrumentation.d.ts +57 -0
- package/dist/lib/services/server/ai/observability/instrumentation.js +170 -0
- package/dist/lib/session/globalSessionState.d.ts +26 -0
- package/dist/lib/session/globalSessionState.js +86 -1
- package/dist/lib/telemetry/index.d.ts +1 -0
- package/dist/lib/telemetry/telemetryService.d.ts +2 -0
- package/dist/lib/telemetry/telemetryService.js +7 -7
- package/dist/lib/types/cli.d.ts +28 -0
- package/dist/lib/types/content.d.ts +18 -5
- package/dist/lib/types/contextTypes.d.ts +1 -1
- package/dist/lib/types/conversation.d.ts +57 -4
- package/dist/lib/types/fileTypes.d.ts +65 -0
- package/dist/lib/types/fileTypes.js +4 -0
- package/dist/lib/types/generateTypes.d.ts +12 -0
- package/dist/lib/types/guardrails.d.ts +103 -0
- package/dist/lib/types/guardrails.js +1 -0
- package/dist/lib/types/index.d.ts +4 -2
- package/dist/lib/types/index.js +4 -0
- package/dist/lib/types/mcpTypes.d.ts +407 -14
- package/dist/lib/types/modelTypes.d.ts +6 -6
- package/dist/lib/types/observability.d.ts +49 -0
- package/dist/lib/types/observability.js +6 -0
- package/dist/lib/types/streamTypes.d.ts +7 -0
- package/dist/lib/types/tools.d.ts +132 -35
- package/dist/lib/utils/csvProcessor.d.ts +68 -0
- package/dist/lib/utils/csvProcessor.js +277 -0
- package/dist/lib/utils/fileDetector.d.ts +57 -0
- package/dist/lib/utils/fileDetector.js +457 -0
- package/dist/lib/utils/imageProcessor.d.ts +10 -0
- package/dist/lib/utils/imageProcessor.js +22 -0
- package/dist/lib/utils/loopUtils.d.ts +71 -0
- package/dist/lib/utils/loopUtils.js +262 -0
- package/dist/lib/utils/messageBuilder.d.ts +2 -1
- package/dist/lib/utils/messageBuilder.js +197 -2
- package/dist/lib/utils/optionsUtils.d.ts +1 -1
- package/dist/mcp/factory.d.ts +2 -157
- package/dist/mcp/flexibleToolValidator.d.ts +1 -5
- package/dist/mcp/index.d.ts +3 -2
- package/dist/mcp/mcpCircuitBreaker.d.ts +1 -75
- package/dist/mcp/mcpClientFactory.d.ts +1 -20
- package/dist/mcp/mcpClientFactory.js +1 -0
- package/dist/mcp/registry.d.ts +3 -10
- package/dist/mcp/servers/agent/directToolsServer.d.ts +1 -1
- package/dist/mcp/servers/aiProviders/aiCoreServer.d.ts +1 -1
- package/dist/mcp/servers/utilities/utilityServer.d.ts +1 -1
- package/dist/mcp/toolDiscoveryService.d.ts +3 -84
- package/dist/mcp/toolRegistry.d.ts +2 -24
- package/dist/middleware/builtin/guardrails.d.ts +5 -16
- package/dist/middleware/builtin/guardrails.js +44 -39
- package/dist/middleware/utils/guardrailsUtils.d.ts +64 -0
- package/dist/middleware/utils/guardrailsUtils.js +387 -0
- package/dist/neurolink.d.ts +36 -7
- package/dist/neurolink.js +141 -0
- package/dist/providers/anthropic.js +47 -3
- package/dist/providers/azureOpenai.js +9 -2
- package/dist/providers/googleAiStudio.js +9 -2
- package/dist/providers/googleVertex.js +12 -2
- package/dist/providers/huggingFace.js +1 -1
- package/dist/providers/litellm.js +1 -1
- package/dist/providers/mistral.js +1 -1
- package/dist/providers/openAI.js +47 -3
- package/dist/services/server/ai/observability/instrumentation.d.ts +57 -0
- package/dist/services/server/ai/observability/instrumentation.js +170 -0
- package/dist/session/globalSessionState.d.ts +26 -0
- package/dist/session/globalSessionState.js +86 -1
- package/dist/telemetry/index.d.ts +1 -0
- package/dist/telemetry/telemetryService.d.ts +2 -0
- package/dist/telemetry/telemetryService.js +7 -7
- package/dist/types/cli.d.ts +28 -0
- package/dist/types/content.d.ts +18 -5
- package/dist/types/contextTypes.d.ts +1 -1
- package/dist/types/conversation.d.ts +57 -4
- package/dist/types/fileTypes.d.ts +65 -0
- package/dist/types/fileTypes.js +4 -0
- package/dist/types/generateTypes.d.ts +12 -0
- package/dist/types/guardrails.d.ts +103 -0
- package/dist/types/guardrails.js +1 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +4 -0
- package/dist/types/mcpTypes.d.ts +407 -14
- package/dist/types/modelTypes.d.ts +6 -6
- package/dist/types/observability.d.ts +49 -0
- package/dist/types/observability.js +6 -0
- package/dist/types/streamTypes.d.ts +7 -0
- package/dist/types/tools.d.ts +132 -35
- package/dist/utils/csvProcessor.d.ts +68 -0
- package/dist/utils/csvProcessor.js +277 -0
- package/dist/utils/fileDetector.d.ts +57 -0
- package/dist/utils/fileDetector.js +457 -0
- package/dist/utils/imageProcessor.d.ts +10 -0
- package/dist/utils/imageProcessor.js +22 -0
- package/dist/utils/loopUtils.d.ts +71 -0
- package/dist/utils/loopUtils.js +262 -0
- package/dist/utils/messageBuilder.d.ts +2 -1
- package/dist/utils/messageBuilder.js +197 -2
- package/dist/utils/optionsUtils.d.ts +1 -1
- package/package.json +18 -16
- package/dist/lib/mcp/contracts/mcpContract.d.ts +0 -106
- package/dist/lib/mcp/contracts/mcpContract.js +0 -5
- package/dist/mcp/contracts/mcpContract.d.ts +0 -106
- 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
|
-
|
|
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;
|
|
@@ -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 {
|
|
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 =
|
|
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) {
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -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
|
*/
|
package/dist/types/content.d.ts
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
/**
|
|
6
6
|
* Text content type for multimodal messages
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
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
|
|
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
|
-
*
|
|
170
|
-
* Contains conversation
|
|
181
|
+
* Base conversation metadata (shared fields across all conversation types)
|
|
182
|
+
* Contains essential conversation information without heavy data arrays
|
|
171
183
|
*/
|
|
172
|
-
export
|
|
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
|
+
};
|
|
@@ -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)
|