@robota-sdk/sessions
Version:
Session and chat management for Robota SDK - multi-session support with independent workspaces
1,330 lines (1,307 loc) • 42.4 kB
JavaScript
'use strict';
var core_star = require('@robota-sdk/core');
var uuid = require('uuid');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var core_star__namespace = /*#__PURE__*/_interopNamespace(core_star);
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget);
// src/index.ts
var index_exports = {};
__export(index_exports, {
BasicSessionStore: () => BasicSessionStore,
ChatInstanceImpl: () => ChatInstanceImpl,
ConversationHistory: () => SimpleConversationHistory,
ConversationServiceImpl: () => ConversationServiceImpl,
DEFAULT_SESSION_CONFIG: () => DEFAULT_SESSION_CONFIG,
EnhancedConversationHistoryImpl: () => EnhancedConversationHistoryImpl,
LoggerFactory: () => LoggerFactory,
MetricsCollectorFactory: () => MetricsCollectorFactory,
MultiProviderAdapterManager: () => MultiProviderAdapterManager,
SessionErrorKey: () => SessionErrorKey,
SessionImpl: () => SessionImpl,
SessionManagerImpl: () => SessionManagerImpl,
SessionOperationError: () => SessionOperationError,
SessionState: () => SessionState,
SimpleConversationHistory: () => SimpleConversationHistory,
SimpleLoggerImpl: () => SimpleLoggerImpl,
SimpleMetricsCollector: () => SimpleMetricsCollector,
SimplePromptTemplate: () => SimplePromptTemplate,
StateTransitionError: () => StateTransitionError,
SystemMessageManagerImpl: () => SystemMessageManagerImpl,
ValidationConstraints: () => ValidationConstraints,
ValidationError: () => ValidationError,
allowsModifications: () => allowsModifications,
attemptTransition: () => attemptTransition,
calculateSessionStats: () => calculateSessionStats,
createInitialMetadata: () => createInitialMetadata,
createSessionError: () => createSessionError,
findNextActiveChat: () => findNextActiveChat,
formatUptime: () => formatUptime,
generateDefaultSessionName: () => generateDefaultSessionName,
generateId: () => generateId,
getErrorMessage: () => getErrorMessage,
getPossibleTransitions: () => getPossibleTransitions,
getStateDescription: () => getStateDescription,
isActiveState: () => isActiveState,
isFinalState: () => isFinalState,
isSessionActive: () => isSessionActive,
isSessionModifiable: () => isSessionModifiable,
isValidTransition: () => isValidTransition,
mergeWithDefaults: () => mergeWithDefaults,
updateTimestamps: () => updateTimestamps,
validateSessionConfig: () => validateSessionConfig,
validateTransitionChain: () => validateTransitionChain,
wouldExceedChatLimit: () => wouldExceedChatLimit
});
// src/types/core.ts
var core_exports = {};
__export(core_exports, {
SessionState: () => SessionState
});
__reExport(core_exports, core_star__namespace);
var SessionState = /* @__PURE__ */ ((SessionState3) => {
SessionState3["ACTIVE"] = "active";
SessionState3["PAUSED"] = "paused";
SessionState3["TERMINATED"] = "terminated";
return SessionState3;
})(SessionState || {});
// src/index.ts
__reExport(index_exports, core_exports);
// src/conversation-history/simple-conversation-history.ts
var SimpleConversationHistory = class {
messages = [];
maxMessages;
constructor(maxMessages) {
this.maxMessages = maxMessages;
}
addMessage(message) {
this.messages.push(message);
if (this.maxMessages && this.messages.length > this.maxMessages) {
this.messages = this.messages.slice(-this.maxMessages);
}
}
getMessages() {
return [...this.messages];
}
getMessageCount() {
return this.messages.length;
}
clear() {
this.messages = [];
}
getLastMessage() {
return this.messages.length > 0 ? this.messages[this.messages.length - 1] : null;
}
getLastUserMessage() {
for (let i = this.messages.length - 1; i >= 0; i--) {
if (this.messages[i].role === "user") {
return this.messages[i];
}
}
return null;
}
getLastAssistantMessage() {
for (let i = this.messages.length - 1; i >= 0; i--) {
if (this.messages[i].role === "assistant") {
return this.messages[i];
}
}
return null;
}
};
// src/utils/simple-logger.ts
var SimpleLoggerImpl = class {
prefix;
constructor(prefix = "SessionSDK") {
this.prefix = prefix;
}
debug(message, ...args) {
console.debug(`[${this.prefix}:DEBUG] ${message}`, ...args);
}
info(message, ...args) {
console.info(`[${this.prefix}:INFO] ${message}`, ...args);
}
warn(message, ...args) {
console.warn(`[${this.prefix}:WARN] ${message}`, ...args);
}
error(message, ...args) {
console.error(`[${this.prefix}:ERROR] ${message}`, ...args);
}
};
// src/utils/simple-metrics.ts
var SimpleMetricsCollector = class {
counters = /* @__PURE__ */ new Map();
gauges = /* @__PURE__ */ new Map();
histograms = /* @__PURE__ */ new Map();
incrementCounter(name, value = 1) {
const current = this.counters.get(name) || 0;
this.counters.set(name, current + value);
}
recordGauge(name, value) {
this.gauges.set(name, value);
}
recordHistogram(name, value) {
const values = this.histograms.get(name) || [];
values.push(value);
this.histograms.set(name, values);
}
getMetrics() {
const result = {};
for (const [name, value] of this.counters) {
result[`counter_${name}`] = value;
}
for (const [name, value] of this.gauges) {
result[`gauge_${name}`] = value;
}
for (const [name, values] of this.histograms) {
if (values.length > 0) {
const sum = values.reduce((a, b) => a + b, 0);
result[`histogram_${name}_count`] = values.length;
result[`histogram_${name}_sum`] = sum;
result[`histogram_${name}_avg`] = sum / values.length;
result[`histogram_${name}_min`] = Math.min(...values);
result[`histogram_${name}_max`] = Math.max(...values);
}
}
return result;
}
reset() {
this.counters.clear();
this.gauges.clear();
this.histograms.clear();
}
};
// src/utils/simple-prompt-template.ts
var SimplePromptTemplate = class _SimplePromptTemplate {
template;
variables;
constructor(template) {
this.template = template;
this.variables = this.extractVariables(template);
}
render(variables) {
let result = this.template;
for (const [key, value] of Object.entries(variables)) {
const placeholder = `{{${key}}}`;
result = result.replace(new RegExp(placeholder, "g"), String(value));
}
return result;
}
getVariables() {
return [...this.variables];
}
extractVariables(template) {
const matches = template.match(/\{\{([^}]+)\}\}/g);
if (!matches) return [];
return matches.map((match) => match.slice(2, -2).trim());
}
static create(template) {
return new _SimplePromptTemplate(template);
}
};
var ChatInstanceImpl = class {
metadata;
config;
robota;
_isActive = false;
_startTime;
constructor(sessionId, config = {}, robotaConfig) {
this._startTime = /* @__PURE__ */ new Date();
this.config = {
chatName: config.chatName || `Chat ${(/* @__PURE__ */ new Date()).getTime()}`,
description: config.description,
robotaConfig: config.robotaConfig || robotaConfig,
autoSave: config.autoSave ?? false,
maxHistorySize: config.maxHistorySize || 1e3
};
this.metadata = {
chatId: uuid.v4(),
sessionId,
chatName: this.config.chatName,
description: this.config.description,
createdAt: this._startTime,
updatedAt: this._startTime,
lastAccessedAt: this._startTime,
messageCount: 0,
isActive: false
};
this.robota = new core_star.Robota({
...this.config.robotaConfig
});
}
// Chat Operations
async sendMessage(content) {
this._updateLastAccessed();
const messageText = typeof content === "string" ? content : content.text || "";
try {
const response = await this.robota.run(messageText);
this.metadata.messageCount = this.robota.limits.getCurrentRequestCount();
return response;
} catch (error) {
throw new Error(`Failed to send message: ${error}`);
}
}
// State Management
activate() {
this._isActive = true;
this.metadata.isActive = true;
this._updateLastAccessed();
}
deactivate() {
this._isActive = false;
this.metadata.isActive = false;
}
// History Management
clearHistory() {
this.robota.conversation.clear();
this.metadata.messageCount = 0;
this._updateLastAccessed();
}
// 간소화된 메서드들
async updateRobotaConfig(config) {
this._updateLastAccessed();
this.config.robotaConfig = { ...this.config.robotaConfig, ...config };
}
getRobotaConfig() {
return this.config.robotaConfig;
}
// 사용하지 않는 복잡한 기능들 제거
async regenerateResponse() {
throw new Error("\uC544\uC9C1 \uAD6C\uD604\uB418\uC9C0 \uC54A\uC74C");
}
async editMessage(messageId, newContent) {
throw new Error("\uC544\uC9C1 \uAD6C\uD604\uB418\uC9C0 \uC54A\uC74C");
}
async deleteMessage(messageId) {
throw new Error("\uC544\uC9C1 \uAD6C\uD604\uB418\uC9C0 \uC54A\uC74C");
}
async exportHistory() {
throw new Error("\uC544\uC9C1 \uAD6C\uD604\uB418\uC9C0 \uC54A\uC74C");
}
async importHistory(data) {
throw new Error("\uC544\uC9C1 \uAD6C\uD604\uB418\uC9C0 \uC54A\uC74C");
}
// Lifecycle - 일단 비워둠
async save() {
this.metadata.updatedAt = /* @__PURE__ */ new Date();
}
async load() {
}
// Utils
getStats() {
return {
messageCount: this.metadata.messageCount,
configurationChanges: 0,
memoryUsage: 0,
createdAt: this.metadata.createdAt,
lastActivity: this.metadata.lastAccessedAt,
totalTokens: this.robota.limits.getCurrentTokensUsed(),
averageResponseTime: void 0
};
}
updateConfig(config) {
Object.assign(this.config, config);
if (config.chatName) {
this.metadata.chatName = config.chatName;
}
if (config.description !== void 0) {
this.metadata.description = config.description;
}
this._updateLastAccessed();
}
_updateLastAccessed() {
this.metadata.lastAccessedAt = /* @__PURE__ */ new Date();
this.metadata.updatedAt = /* @__PURE__ */ new Date();
}
// history 프로퍼티를 위한 getter (호환성)
get history() {
return {
getMessageCount: () => this.robota.limits.getCurrentRequestCount(),
clear: () => this.robota.conversation.clear()
};
}
};
// src/state/session-state-machine.ts
var STATE_TRANSITIONS = [
// From ACTIVE
{ from: "active" /* ACTIVE */, to: "paused" /* PAUSED */, action: "pause" },
{ from: "active" /* ACTIVE */, to: "archived" /* ARCHIVED */, action: "archive" },
{ from: "active" /* ACTIVE */, to: "terminated" /* TERMINATED */, action: "terminate" },
// From PAUSED
{ from: "paused" /* PAUSED */, to: "active" /* ACTIVE */, action: "resume" },
{ from: "paused" /* PAUSED */, to: "archived" /* ARCHIVED */, action: "archive" },
{ from: "paused" /* PAUSED */, to: "terminated" /* TERMINATED */, action: "terminate" },
// From ARCHIVED
{ from: "archived" /* ARCHIVED */, to: "active" /* ACTIVE */, action: "restore" },
{ from: "archived" /* ARCHIVED */, to: "terminated" /* TERMINATED */, action: "terminate" }
// TERMINATED is final state - no transitions allowed
];
function isValidTransition(currentState, targetState, action, context) {
if (currentState === targetState) {
return true;
}
const transition = STATE_TRANSITIONS.find(
(t) => t.from === currentState && t.to === targetState && t.action === action
);
if (!transition) {
return false;
}
if (transition.condition && context) {
return transition.condition(context);
}
return true;
}
function attemptTransition(currentState, targetState, action, context) {
if (!isValidTransition(currentState, targetState, action, context)) {
return {
success: false,
error: `Invalid state transition: ${currentState} -> ${targetState} (action: ${action})`
};
}
return {
success: true,
newState: targetState
};
}
function getPossibleTransitions(currentState) {
return STATE_TRANSITIONS.filter((t) => t.from === currentState).map((t) => ({ state: t.to, action: t.action }));
}
function isFinalState(state) {
return state === "terminated" /* TERMINATED */;
}
function isActiveState(state) {
return state === "active" /* ACTIVE */;
}
function allowsModifications(state) {
return state === "active" /* ACTIVE */ || state === "paused" /* PAUSED */;
}
function getStateDescription(state) {
const descriptions = {
["active" /* ACTIVE */]: "Session is active and ready for interactions",
["paused" /* PAUSED */]: "Session is paused and can be resumed",
["archived" /* ARCHIVED */]: "Session is archived for long-term storage",
["terminated" /* TERMINATED */]: "Session is permanently terminated"
};
return descriptions[state];
}
function validateTransitionChain(transitions) {
const errors = [];
for (let i = 0; i < transitions.length; i++) {
const transition = transitions[i];
if (!isValidTransition(transition.from, transition.to, transition.action)) {
errors.push(
`Step ${i + 1}: Invalid transition ${transition.from} -> ${transition.to} (${transition.action})`
);
}
if (i > 0 && transitions[i - 1].to !== transition.from) {
errors.push(
`Step ${i + 1}: State mismatch - previous step ended at ${transitions[i - 1].to}, current step starts at ${transition.from}`
);
}
}
return {
valid: errors.length === 0,
errors
};
}
// src/constants/error-messages.ts
var SessionErrorKey = /* @__PURE__ */ ((SessionErrorKey2) => {
SessionErrorKey2["MAX_CHATS_REACHED"] = "MAX_CHATS_REACHED";
SessionErrorKey2["CHAT_NOT_FOUND"] = "CHAT_NOT_FOUND";
SessionErrorKey2["INVALID_STATE_TRANSITION"] = "INVALID_STATE_TRANSITION";
SessionErrorKey2["OPERATION_NOT_ALLOWED"] = "OPERATION_NOT_ALLOWED";
SessionErrorKey2["SESSION_TERMINATED"] = "SESSION_TERMINATED";
SessionErrorKey2["INVALID_CONFIG"] = "INVALID_CONFIG";
SessionErrorKey2["SAVE_FAILED"] = "SAVE_FAILED";
SessionErrorKey2["LOAD_FAILED"] = "LOAD_FAILED";
return SessionErrorKey2;
})(SessionErrorKey || {});
var ERROR_MESSAGES = {
["MAX_CHATS_REACHED" /* MAX_CHATS_REACHED */]: "Maximum number of chats ({maxChats}) reached",
["CHAT_NOT_FOUND" /* CHAT_NOT_FOUND */]: 'Chat with ID "{chatId}" not found',
["INVALID_STATE_TRANSITION" /* INVALID_STATE_TRANSITION */]: "Invalid state transition from {currentState} to {targetState}",
["OPERATION_NOT_ALLOWED" /* OPERATION_NOT_ALLOWED */]: 'Operation "{operation}" not allowed in state {currentState}',
["SESSION_TERMINATED" /* SESSION_TERMINATED */]: "Session is terminated and cannot be modified",
["INVALID_CONFIG" /* INVALID_CONFIG */]: "Invalid configuration: {reason}",
["SAVE_FAILED" /* SAVE_FAILED */]: "Failed to save session: {reason}",
["LOAD_FAILED" /* LOAD_FAILED */]: "Failed to load session: {reason}"
};
function getErrorMessage(key, params = {}) {
let message = ERROR_MESSAGES[key];
for (const [paramKey, paramValue] of Object.entries(params)) {
message = message.replace(`{${paramKey}}`, String(paramValue));
}
return message;
}
function createSessionError(key, params = {}) {
const message = getErrorMessage(key, params);
const error = new Error(message);
error.name = "SessionError";
return error;
}
var SessionOperationError = class extends Error {
code;
context;
constructor(code, context = {}) {
const message = getErrorMessage(code, context);
super(message);
this.name = "SessionOperationError";
this.code = code;
this.context = context;
}
};
var StateTransitionError = class extends SessionOperationError {
currentState;
targetState;
action;
constructor(currentState, targetState, action) {
super("INVALID_STATE_TRANSITION" /* INVALID_STATE_TRANSITION */, {
currentState,
targetState,
action
});
this.currentState = currentState;
this.targetState = targetState;
this.action = action;
}
};
var ValidationError = class extends Error {
field;
value;
constraint;
constructor(field, value, constraint) {
super(`Validation failed for field "${field}": ${constraint} (got: ${value})`);
this.name = "ValidationError";
this.field = field;
this.value = value;
this.constraint = constraint;
}
};
var ValidationConstraints = {
required: (field) => `${field} is required`,
minLength: (field, min) => `${field} must be at least ${min} characters`,
maxLength: (field, max) => `${field} must be at most ${max} characters`,
positive: (field) => `${field} must be a positive number`,
range: (field, min, max) => `${field} must be between ${min} and ${max}`
};
// src/utils/session-utils.ts
var DEFAULT_SESSION_CONFIG = {
sessionName: "",
description: void 0,
autoSave: false,
saveInterval: 3e5,
// 5 minutes
maxChats: 20,
retentionPeriod: 30
// days
};
function generateDefaultSessionName(timestamp) {
const time = timestamp || /* @__PURE__ */ new Date();
return `Session ${time.getTime()}`;
}
function validateSessionConfig(config) {
const errors = [];
if (config.sessionName !== void 0) {
if (typeof config.sessionName !== "string") {
errors.push(new ValidationError("sessionName", config.sessionName, "must be a string"));
} else if (config.sessionName.length === 0) {
errors.push(new ValidationError("sessionName", config.sessionName, ValidationConstraints.required("sessionName")));
} else if (config.sessionName.length > 100) {
errors.push(new ValidationError("sessionName", config.sessionName, ValidationConstraints.maxLength("sessionName", 100)));
}
}
if (config.description !== void 0 && typeof config.description !== "string") {
errors.push(new ValidationError("description", config.description, "must be a string"));
}
if (config.maxChats !== void 0) {
if (typeof config.maxChats !== "number" || !Number.isInteger(config.maxChats)) {
errors.push(new ValidationError("maxChats", config.maxChats, "must be an integer"));
} else if (config.maxChats <= 0) {
errors.push(new ValidationError("maxChats", config.maxChats, ValidationConstraints.positive("maxChats")));
} else if (config.maxChats > 100) {
errors.push(new ValidationError("maxChats", config.maxChats, ValidationConstraints.range("maxChats", 1, 100)));
}
}
if (config.saveInterval !== void 0) {
if (typeof config.saveInterval !== "number" || !Number.isInteger(config.saveInterval)) {
errors.push(new ValidationError("saveInterval", config.saveInterval, "must be an integer"));
} else if (config.saveInterval < 6e4) {
errors.push(new ValidationError("saveInterval", config.saveInterval, "must be at least 60000ms (1 minute)"));
}
}
if (config.retentionPeriod !== void 0) {
if (typeof config.retentionPeriod !== "number" || !Number.isInteger(config.retentionPeriod)) {
errors.push(new ValidationError("retentionPeriod", config.retentionPeriod, "must be an integer"));
} else if (config.retentionPeriod <= 0) {
errors.push(new ValidationError("retentionPeriod", config.retentionPeriod, ValidationConstraints.positive("retentionPeriod")));
}
}
return {
valid: errors.length === 0,
errors
};
}
function mergeWithDefaults(config) {
const merged = { ...DEFAULT_SESSION_CONFIG, ...config };
if (!merged.sessionName) {
merged.sessionName = generateDefaultSessionName();
}
return merged;
}
function createInitialMetadata(sessionId, userId, config) {
const now = /* @__PURE__ */ new Date();
return {
sessionId,
userId,
sessionName: config.sessionName,
description: config.description,
createdAt: now,
updatedAt: now,
lastAccessedAt: now,
state: "active" /* ACTIVE */,
chatCount: 0,
activeChatId: void 0
};
}
function updateTimestamps(metadata) {
const now = /* @__PURE__ */ new Date();
return {
...metadata,
lastAccessedAt: now,
updatedAt: now
};
}
function calculateSessionStats(metadata, chats, startTime) {
let totalMessages = 0;
for (const chat of chats) {
totalMessages += chat.metadata.messageCount;
}
return {
chatCount: metadata.chatCount,
totalMessages,
memoryUsage: 0,
// TODO: Implement memory usage calculation
diskUsage: 0,
// TODO: Implement disk usage calculation
createdAt: metadata.createdAt,
lastActivity: metadata.lastAccessedAt,
uptime: Date.now() - startTime.getTime()
};
}
function findNextActiveChat(chats, removedChatId, currentActiveChatId) {
if (currentActiveChatId !== removedChatId) {
return currentActiveChatId;
}
const remainingChatIds = Array.from(chats.keys()).filter((id) => id !== removedChatId);
return remainingChatIds.length > 0 ? remainingChatIds[0] : void 0;
}
function wouldExceedChatLimit(currentCount, maxChats) {
return currentCount >= maxChats;
}
function formatUptime(uptimeMs) {
const seconds = Math.floor(uptimeMs / 1e3);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) {
return `${days}d ${hours % 24}h ${minutes % 60}m`;
} else if (hours > 0) {
return `${hours}h ${minutes % 60}m`;
} else if (minutes > 0) {
return `${minutes}m ${seconds % 60}s`;
} else {
return `${seconds}s`;
}
}
function isSessionModifiable(state) {
return state === "active" /* ACTIVE */ || state === "paused" /* PAUSED */;
}
function isSessionActive(state) {
return state === "active" /* ACTIVE */;
}
// src/session/session-impl.ts
var SessionImpl = class {
metadata;
config;
_chats = /* @__PURE__ */ new Map();
_activeChatId;
_startTime;
constructor(userId, config = {}) {
const validation = validateSessionConfig(config);
if (!validation.valid) {
throw new SessionOperationError("INVALID_CONFIG" /* INVALID_CONFIG */, {
reason: validation.errors.map((e) => e.message).join(", ")
});
}
this._startTime = /* @__PURE__ */ new Date();
const mergedConfig = mergeWithDefaults(config);
this.config = mergedConfig;
this.metadata = createInitialMetadata(uuid.v4(), userId, mergedConfig);
}
// Chat Management - using pure functions
async createNewChat(config) {
this._ensureOperationAllowed("createNewChat");
this._updateLastAccessed();
if (wouldExceedChatLimit(this.metadata.chatCount, this.config.maxChats)) {
throw new SessionOperationError("MAX_CHATS_REACHED" /* MAX_CHATS_REACHED */, {
maxChats: this.config.maxChats
});
}
const chat = new ChatInstanceImpl(
this.metadata.sessionId,
config,
config?.robotaConfig
);
this._chats.set(chat.metadata.chatId, chat);
this.metadata.chatCount++;
if (this.metadata.chatCount === 1) {
await this._setActiveChat(chat.metadata.chatId);
}
return chat;
}
getChat(chatId) {
return this._chats.get(chatId);
}
getAllChats() {
return Array.from(this._chats.values());
}
async switchToChat(chatId) {
this._ensureOperationAllowed("switchToChat");
this._updateLastAccessed();
const chat = this._chats.get(chatId);
if (!chat) {
throw new SessionOperationError("CHAT_NOT_FOUND" /* CHAT_NOT_FOUND */, { chatId });
}
await this._setActiveChat(chatId);
}
async removeChat(chatId) {
this._ensureOperationAllowed("removeChat");
this._updateLastAccessed();
const chat = this._chats.get(chatId);
if (!chat) {
throw new SessionOperationError("CHAT_NOT_FOUND" /* CHAT_NOT_FOUND */, { chatId });
}
const nextActiveChatId = findNextActiveChat(this._chats, chatId, this._activeChatId);
this._chats.delete(chatId);
this.metadata.chatCount--;
if (nextActiveChatId) {
await this._setActiveChat(nextActiveChatId);
} else {
this._activeChatId = void 0;
this.metadata.activeChatId = void 0;
}
}
getActiveChat() {
if (!this._activeChatId) {
return void 0;
}
return this._chats.get(this._activeChatId);
}
// Session State Management - using state machine
async pause() {
await this._transitionState("paused" /* PAUSED */, "pause");
this._deactivateAllChats();
}
async resume() {
await this._transitionState("active" /* ACTIVE */, "resume");
if (this._activeChatId) {
const activeChat = this._chats.get(this._activeChatId);
if (activeChat) {
activeChat.activate();
}
}
}
async archive() {
await this._transitionState("archived" /* ARCHIVED */, "archive");
this._deactivateAllChats();
}
async terminate() {
await this._transitionState("terminated" /* TERMINATED */, "terminate");
this._deactivateAllChats();
this._chats.clear();
this._activeChatId = void 0;
this.metadata.activeChatId = void 0;
this.metadata.chatCount = 0;
}
// Lifecycle
async save() {
this.metadata.updatedAt = /* @__PURE__ */ new Date();
}
async load() {
}
// Utils - using pure functions
getState() {
return this.metadata.state;
}
updateConfig(config) {
this._ensureOperationAllowed("updateConfig");
const validation = validateSessionConfig(config);
if (!validation.valid) {
throw new SessionOperationError("INVALID_CONFIG" /* INVALID_CONFIG */, {
reason: validation.errors.map((e) => e.message).join(", ")
});
}
Object.assign(this.config, config);
if (config.sessionName) {
this.metadata.sessionName = config.sessionName;
}
if (config.description !== void 0) {
this.metadata.description = config.description;
}
this._updateLastAccessed();
}
getStats() {
return calculateSessionStats(
this.metadata,
this.getAllChats(),
this._startTime
);
}
// Private helper methods
_updateLastAccessed() {
Object.assign(this.metadata, updateTimestamps(this.metadata));
}
async _transitionState(targetState, action) {
const result = attemptTransition(this.metadata.state, targetState, action);
if (!result.success) {
throw new StateTransitionError(this.metadata.state, targetState, action);
}
this.metadata.state = targetState;
this._updateLastAccessed();
}
async _setActiveChat(chatId) {
if (this._activeChatId) {
const currentChat = this._chats.get(this._activeChatId);
if (currentChat) {
currentChat.deactivate();
}
}
const newChat = this._chats.get(chatId);
if (newChat && isActiveState(this.metadata.state)) {
newChat.activate();
}
this._activeChatId = chatId;
this.metadata.activeChatId = chatId;
}
_deactivateAllChats() {
for (const chat of this._chats.values()) {
chat.deactivate();
}
}
_ensureOperationAllowed(operation) {
if (isFinalState(this.metadata.state)) {
throw new SessionOperationError("SESSION_TERMINATED" /* SESSION_TERMINATED */);
}
if (!isSessionModifiable(this.metadata.state)) {
throw new SessionOperationError("OPERATION_NOT_ALLOWED" /* OPERATION_NOT_ALLOWED */, {
operation,
currentState: this.metadata.state
});
}
}
};
// src/session-manager/session-manager-impl.ts
var SessionManagerImpl = class {
sessions = /* @__PURE__ */ new Map();
userSessions = /* @__PURE__ */ new Map();
config;
constructor(config = {}) {
this.config = {
maxActiveSessions: config.maxActiveSessions || 10,
// Reduced from 50 to 10
autoCleanup: config.autoCleanup ?? true,
cleanupInterval: config.cleanupInterval || 36e5,
// Changed to 1 hour
memoryThreshold: config.memoryThreshold || 100,
// Reduced to 100MB
storage: config.storage
};
}
async createSession(userId, config) {
const userSessionIds = this.userSessions.get(userId) || /* @__PURE__ */ new Set();
if (userSessionIds.size >= this.config.maxActiveSessions) {
throw new Error(`Maximum session count (${this.config.maxActiveSessions}) reached for user ${userId}`);
}
const session = new SessionImpl(userId, config);
this.sessions.set(session.metadata.sessionId, session);
if (!this.userSessions.has(userId)) {
this.userSessions.set(userId, /* @__PURE__ */ new Set());
}
this.userSessions.get(userId).add(session.metadata.sessionId);
return session;
}
getSession(sessionId) {
return this.sessions.get(sessionId);
}
getUserSessions(userId) {
const sessionIds = this.userSessions.get(userId) || /* @__PURE__ */ new Set();
const sessions = [];
for (const sessionId of sessionIds) {
const session = this.sessions.get(sessionId);
if (session) {
sessions.push(session);
}
}
return sessions;
}
async removeSession(sessionId) {
const session = this.sessions.get(sessionId);
if (!session) {
return;
}
await session.terminate();
this.sessions.delete(sessionId);
const userSessionIds = this.userSessions.get(session.metadata.userId);
if (userSessionIds) {
userSessionIds.delete(sessionId);
if (userSessionIds.size === 0) {
this.userSessions.delete(session.metadata.userId);
}
}
}
async pauseSession(sessionId) {
const session = this.sessions.get(sessionId);
if (session) {
await session.pause();
}
}
async resumeSession(sessionId) {
const session = this.sessions.get(sessionId);
if (session) {
await session.resume();
}
}
async archiveSession(sessionId) {
const session = this.sessions.get(sessionId);
if (session) {
await session.archive();
}
}
getActiveSessionCount() {
let count = 0;
for (const session of this.sessions.values()) {
if (session.getState() === "active") {
count++;
}
}
return count;
}
// Simplified cleanup logic
async cleanup() {
if (!this.config.autoCleanup) {
return;
}
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3);
const sessionsToRemove = [];
for (const [sessionId, session] of this.sessions) {
if (session.metadata.lastAccessedAt < sevenDaysAgo) {
sessionsToRemove.push(sessionId);
}
}
for (const sessionId of sessionsToRemove) {
await this.removeSession(sessionId);
}
}
async shutdown() {
for (const session of this.sessions.values()) {
await session.terminate();
}
this.sessions.clear();
this.userSessions.clear();
}
// Simplified statistics
getStats() {
let activeSessions = 0;
let pausedSessions = 0;
let archivedSessions = 0;
for (const session of this.sessions.values()) {
switch (session.getState()) {
case "active":
activeSessions++;
break;
case "paused":
pausedSessions++;
break;
case "archived":
archivedSessions++;
break;
}
}
return {
totalSessions: this.sessions.size,
activeSessions,
pausedSessions,
archivedSessions,
memoryUsage: 0
// To be implemented later
};
}
};
// src/session-manager/basic-session-store.ts
var BasicSessionStore = class {
sessions = /* @__PURE__ */ new Map();
async save(session) {
this.sessions.set(session.id, { ...session });
}
async load(sessionId) {
const session = this.sessions.get(sessionId);
return session ? { ...session } : null;
}
async delete(sessionId) {
return this.sessions.delete(sessionId);
}
async list(userId) {
const sessions = Array.from(this.sessions.values());
if (userId) {
return sessions.filter((session) => session.userId === userId);
}
return sessions;
}
async exists(sessionId) {
return this.sessions.has(sessionId);
}
async clear() {
this.sessions.clear();
}
// Additional utility methods for in-memory store
size() {
return this.sessions.size;
}
getAllSessions() {
return Array.from(this.sessions.values());
}
};
// src/system-message/system-message-manager-impl.ts
var SystemMessageManagerImpl = class {
systemMessages = [];
setSystemPrompt(prompt) {
this.systemMessages = [{
role: "system",
content: prompt,
timestamp: /* @__PURE__ */ new Date()
}];
}
addSystemMessage(content) {
this.systemMessages.push({
role: "system",
content,
timestamp: /* @__PURE__ */ new Date()
});
}
getSystemMessages() {
return [...this.systemMessages];
}
clearSystemMessages() {
this.systemMessages = [];
}
hasSystemMessages() {
return this.systemMessages.length > 0;
}
};
var MultiProviderAdapterManager = class {
providers = /* @__PURE__ */ new Map();
defaultProvider = null;
addProvider(name, provider) {
this.providers.set(name, provider);
}
getProvider(name) {
return this.providers.get(name) || null;
}
setDefaultProvider(name) {
if (this.providers.has(name)) {
this.defaultProvider = name;
}
}
getDefaultProvider() {
return this.defaultProvider;
}
};
// src/conversation/conversation-service-impl.ts
var ConversationServiceImpl = class {
conversationHistory;
constructor(maxMessages) {
this.conversationHistory = new SimpleConversationHistory(maxMessages);
}
addMessage(message) {
this.conversationHistory.addMessage(message);
}
getMessages() {
return this.conversationHistory.getMessages();
}
getConversationSummary() {
const messages = this.conversationHistory.getMessages();
const messageCount = messages.length;
const lastMessage = this.conversationHistory.getLastMessage();
return `Conversation with ${messageCount} messages. Last message: ${lastMessage ? `${lastMessage.role} - ${lastMessage.content?.slice(0, 50) || "No content"}...` : "None"}`;
}
clearConversation() {
this.conversationHistory.clear();
}
};
// src/utils/logger-factory.ts
var LoggerFactory = class {
static instances = /* @__PURE__ */ new Map();
static getLogger(name) {
if (!this.instances.has(name)) {
this.instances.set(name, new SimpleLoggerImpl(name));
}
return this.instances.get(name);
}
static createLogger(name) {
return new SimpleLoggerImpl(name);
}
static clearCache() {
this.instances.clear();
}
};
// src/utils/metrics-collector-factory.ts
var MetricsCollectorFactory = class {
static instances = /* @__PURE__ */ new Map();
static getCollector(name) {
if (!this.instances.has(name)) {
this.instances.set(name, new SimpleMetricsCollector());
}
return this.instances.get(name);
}
static createCollector() {
return new SimpleMetricsCollector();
}
static clearCache() {
this.instances.clear();
}
static getAllMetrics() {
const allMetrics = {};
for (const [name, collector] of this.instances) {
allMetrics[name] = collector.getMetrics();
}
return allMetrics;
}
};
var EnhancedConversationHistoryImpl = class {
messages = [];
configurations = [];
maxHistorySize;
constructor(maxHistorySize = 1e3) {
this.maxHistorySize = maxHistorySize;
}
// ConversationHistory interface implementation
addMessage(message) {
this.messages.push(message);
this._enforceMaxSize();
}
addUserMessage(content, metadata) {
this.addMessage({
role: "user",
content,
timestamp: /* @__PURE__ */ new Date(),
metadata
});
}
addAssistantMessage(content, toolCalls, metadata) {
this.addMessage({
role: "assistant",
content,
toolCalls,
timestamp: /* @__PURE__ */ new Date(),
metadata
});
}
addSystemMessage(content, metadata) {
this.addMessage({
role: "system",
content,
timestamp: /* @__PURE__ */ new Date(),
metadata
});
}
addToolMessage(toolCallId, content, toolName, metadata) {
this.addMessage({
role: "tool",
content,
name: toolName,
toolCallId,
timestamp: /* @__PURE__ */ new Date(),
metadata
});
}
addToolMessageWithId(content, toolCallId, toolName, metadata) {
this.addMessage({
role: "tool",
content,
name: toolName,
toolCallId,
timestamp: /* @__PURE__ */ new Date(),
metadata
});
}
getMessages() {
return [...this.messages];
}
getMessagesByRole(role) {
return this.messages.filter((msg) => msg.role === role);
}
getRecentMessages(count) {
return this.messages.slice(-count);
}
clear() {
this.messages = [];
this.configurations = [];
}
getMessageCount() {
return this.messages.length;
}
// Enhanced functionality for configuration tracking
addConfigurationChange(change) {
this.configurations.push({
...change,
id: change.id || uuid.v4(),
timestamp: change.timestamp || /* @__PURE__ */ new Date()
});
}
getConfigurationHistory() {
return [...this.configurations];
}
clearConfigurationHistory() {
this.configurations = [];
}
// Additional utility methods
updateMessage(index, content) {
if (index >= 0 && index < this.messages.length) {
this.messages[index] = {
...this.messages[index],
content,
timestamp: /* @__PURE__ */ new Date()
};
return true;
}
return false;
}
removeMessage(index) {
if (index >= 0 && index < this.messages.length) {
this.messages.splice(index, 1);
return true;
}
return false;
}
getConfigurationChangeCount() {
return this.configurations.length;
}
// Export/Import functionality
export() {
return JSON.stringify({
messages: this.messages,
configurations: this.configurations,
exportedAt: /* @__PURE__ */ new Date()
}, null, 2);
}
import(data) {
try {
const parsed = JSON.parse(data);
if (parsed.messages && Array.isArray(parsed.messages)) {
this.messages = parsed.messages;
}
if (parsed.configurations && Array.isArray(parsed.configurations)) {
this.configurations = parsed.configurations;
}
} catch (error) {
throw new Error(`Failed to import conversation history: ${error}`);
}
}
// Memory management
getMemoryUsage() {
const messagesSize = JSON.stringify(this.messages).length;
const configurationsSize = JSON.stringify(this.configurations).length;
return (messagesSize + configurationsSize) / (1024 * 1024);
}
_enforceMaxSize() {
if (this.messages.length > this.maxHistorySize) {
const systemMessages = this.messages.filter((m) => m.role === "system");
const otherMessages = this.messages.filter((m) => m.role !== "system");
const messagesToKeep = this.maxHistorySize - systemMessages.length;
const recentMessages = otherMessages.slice(-messagesToKeep);
this.messages = [...systemMessages, ...recentMessages];
}
}
};
// src/index.ts
__reExport(index_exports, core_exports);
function generateId() {
return uuid.v4();
}
exports.BasicSessionStore = BasicSessionStore;
exports.ChatInstanceImpl = ChatInstanceImpl;
exports.ConversationHistory = SimpleConversationHistory;
exports.ConversationServiceImpl = ConversationServiceImpl;
exports.DEFAULT_SESSION_CONFIG = DEFAULT_SESSION_CONFIG;
exports.EnhancedConversationHistoryImpl = EnhancedConversationHistoryImpl;
exports.LoggerFactory = LoggerFactory;
exports.MetricsCollectorFactory = MetricsCollectorFactory;
exports.MultiProviderAdapterManager = MultiProviderAdapterManager;
exports.SessionErrorKey = SessionErrorKey;
exports.SessionImpl = SessionImpl;
exports.SessionManagerImpl = SessionManagerImpl;
exports.SessionOperationError = SessionOperationError;
exports.SessionState = SessionState;
exports.SimpleConversationHistory = SimpleConversationHistory;
exports.SimpleLoggerImpl = SimpleLoggerImpl;
exports.SimpleMetricsCollector = SimpleMetricsCollector;
exports.SimplePromptTemplate = SimplePromptTemplate;
exports.StateTransitionError = StateTransitionError;
exports.SystemMessageManagerImpl = SystemMessageManagerImpl;
exports.ValidationConstraints = ValidationConstraints;
exports.ValidationError = ValidationError;
exports.allowsModifications = allowsModifications;
exports.attemptTransition = attemptTransition;
exports.calculateSessionStats = calculateSessionStats;
exports.createInitialMetadata = createInitialMetadata;
exports.createSessionError = createSessionError;
exports.findNextActiveChat = findNextActiveChat;
exports.formatUptime = formatUptime;
exports.generateDefaultSessionName = generateDefaultSessionName;
exports.generateId = generateId;
exports.getErrorMessage = getErrorMessage;
exports.getPossibleTransitions = getPossibleTransitions;
exports.getStateDescription = getStateDescription;
exports.isActiveState = isActiveState;
exports.isFinalState = isFinalState;
exports.isSessionActive = isSessionActive;
exports.isSessionModifiable = isSessionModifiable;
exports.isValidTransition = isValidTransition;
exports.mergeWithDefaults = mergeWithDefaults;
exports.updateTimestamps = updateTimestamps;
exports.validateSessionConfig = validateSessionConfig;
exports.validateTransitionChain = validateTransitionChain;
exports.wouldExceedChatLimit = wouldExceedChatLimit;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map