@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
181 lines • 6.36 kB
JavaScript
import { nanoid } from "nanoid";
import { NeuroLink } from "../neurolink.js";
import { buildObservabilityConfigFromEnv } from "../utils/observabilityHelpers.js";
/**
* Build mcp.outputLimits config from environment variables.
* Reads NEUROLINK_MCP_OUTPUT_STRATEGY and NEUROLINK_MCP_MAX_OUTPUT_BYTES.
* Returns undefined when neither variable is set (no overhead).
*/
function buildMcpOutputLimitsFromEnv() {
const strategyRaw = process.env.NEUROLINK_MCP_OUTPUT_STRATEGY;
const maxBytesRaw = process.env.NEUROLINK_MCP_MAX_OUTPUT_BYTES;
const warnBytesRaw = process.env.NEUROLINK_MCP_WARN_OUTPUT_BYTES;
if (!strategyRaw && !maxBytesRaw) {
return undefined;
}
const strategy = strategyRaw === "inline" || strategyRaw === "externalize"
? strategyRaw
: "externalize"; // safe default when only maxBytes is set
const maxBytes = maxBytesRaw ? parseInt(maxBytesRaw, 10) : undefined;
const warnBytes = warnBytesRaw ? parseInt(warnBytesRaw, 10) : undefined;
return {
strategy,
...(maxBytes !== undefined && Number.isFinite(maxBytes) && maxBytes >= 0
? { maxBytes }
: {}),
...(warnBytes !== undefined && Number.isFinite(warnBytes) && warnBytes >= 0
? { warnBytes }
: {}),
};
}
export class GlobalSessionManager {
static instance;
loopSession = null;
static getInstance() {
if (!GlobalSessionManager.instance) {
GlobalSessionManager.instance = new GlobalSessionManager();
}
return GlobalSessionManager.instance;
}
setLoopSession(config) {
const sessionId = `NL_${nanoid()}`;
const neurolinkOptions = {};
if (config?.enabled) {
neurolinkOptions.conversationMemory = {
enabled: true,
maxSessions: config.maxSessions,
maxTurnsPerSession: config.maxTurnsPerSession,
};
}
// Add observability config from environment variables (CLI usage)
const observabilityConfig = buildObservabilityConfigFromEnv();
if (observabilityConfig) {
neurolinkOptions.observability = observabilityConfig;
}
// Add MCP output limits from environment variables (CLI usage)
const mcpOutputLimits = buildMcpOutputLimitsFromEnv();
if (mcpOutputLimits) {
neurolinkOptions.mcp = {
...neurolinkOptions.mcp,
outputLimits: mcpOutputLimits,
};
}
this.loopSession = {
neurolinkInstance: new NeuroLink(neurolinkOptions),
sessionId,
isActive: true,
conversationMemoryConfig: config,
sessionVariables: {},
};
return sessionId;
}
/**
* Restore a loop session with an existing sessionId and NeuroLink instance
* Used for conversation restoration
*/
restoreLoopSession(sessionId, neurolinkInstance, config, sessionVariables) {
this.loopSession = {
neurolinkInstance,
sessionId,
isActive: true,
conversationMemoryConfig: config,
sessionVariables: sessionVariables || {},
};
}
/**
* Update session variables during restoration
*/
restoreSessionVariables(variables) {
const session = this.getLoopSession();
if (session) {
session.sessionVariables = { ...session.sessionVariables, ...variables };
}
}
/**
* Check if a session is currently active
*/
hasActiveSession() {
return this.loopSession?.isActive ?? false;
}
/**
* Get current session metadata for restoration purposes
*/
getSessionMetadata() {
const session = this.getLoopSession();
return {
sessionId: session?.sessionId,
conversationMemoryConfig: session?.conversationMemoryConfig,
sessionVariables: session?.sessionVariables || {},
isActive: session?.isActive ?? false,
};
}
/**
* Update the sessionId of the current session (used during restoration)
*/
updateSessionId(newSessionId) {
const session = this.getLoopSession();
if (session) {
session.sessionId = newSessionId;
}
}
getLoopSession() {
return this.loopSession?.isActive ? this.loopSession : null;
}
clearLoopSession() {
if (this.loopSession) {
this.loopSession.isActive = false;
this.loopSession = null;
}
}
getOrCreateNeuroLink() {
const session = this.getLoopSession();
if (session) {
return session.neurolinkInstance;
}
// Create new NeuroLink with observability config from environment (CLI usage)
const observabilityConfig = buildObservabilityConfigFromEnv();
const mcpOutputLimits = buildMcpOutputLimitsFromEnv();
const options = {};
if (observabilityConfig) {
options.observability = observabilityConfig;
}
if (mcpOutputLimits) {
options.mcp = { outputLimits: mcpOutputLimits };
}
return new NeuroLink(Object.keys(options).length ? options : undefined);
}
getCurrentSessionId() {
return this.getLoopSession()?.sessionId;
}
// Session variable management
setSessionVariable(key, value) {
const session = this.getLoopSession();
if (session) {
session.sessionVariables[key] = value;
}
}
getSessionVariable(key) {
const session = this.getLoopSession();
return session?.sessionVariables[key];
}
getSessionVariables() {
const session = this.getLoopSession();
return session?.sessionVariables || {};
}
unsetSessionVariable(key) {
const session = this.getLoopSession();
if (session && key in session.sessionVariables) {
delete session.sessionVariables[key];
return true;
}
return false;
}
clearSessionVariables() {
const session = this.getLoopSession();
if (session) {
session.sessionVariables = {};
}
}
}
export const globalSession = GlobalSessionManager.getInstance();
//# sourceMappingURL=globalSessionState.js.map