| const crypto = require('crypto') |
| const logger = require('./logger') |
|
|
| class SessionHelper { |
| |
| |
| |
| |
| |
| |
| generateSessionHash(requestBody) { |
| if (!requestBody || typeof requestBody !== 'object') { |
| return null |
| } |
|
|
| |
| if (requestBody.metadata && requestBody.metadata.user_id) { |
| |
| const userIdString = requestBody.metadata.user_id |
| const sessionMatch = userIdString.match(/session_([a-f0-9-]{36})/) |
| if (sessionMatch && sessionMatch[1]) { |
| const sessionId = sessionMatch[1] |
| |
| logger.debug(`📋 Session ID extracted from metadata.user_id: ${sessionId}`) |
| return sessionId |
| } |
| } |
|
|
| let cacheableContent = '' |
| const system = requestBody.system || '' |
| const messages = requestBody.messages || [] |
|
|
| |
| |
| if (Array.isArray(system)) { |
| for (const part of system) { |
| if (part && part.cache_control && part.cache_control.type === 'ephemeral') { |
| cacheableContent += part.text || '' |
| } |
| } |
| } |
|
|
| |
| for (const msg of messages) { |
| const content = msg.content || '' |
| let hasCacheControl = false |
|
|
| if (Array.isArray(content)) { |
| for (const part of content) { |
| if (part && part.cache_control && part.cache_control.type === 'ephemeral') { |
| hasCacheControl = true |
| break |
| } |
| } |
| } else if ( |
| typeof content === 'string' && |
| msg.cache_control && |
| msg.cache_control.type === 'ephemeral' |
| ) { |
| hasCacheControl = true |
| } |
|
|
| if (hasCacheControl) { |
| for (const message of messages) { |
| let messageText = '' |
| if (typeof message.content === 'string') { |
| messageText = message.content |
| } else if (Array.isArray(message.content)) { |
| messageText = message.content |
| .filter((part) => part.type === 'text') |
| .map((part) => part.text || '') |
| .join('') |
| } |
|
|
| if (messageText) { |
| cacheableContent += messageText |
| break |
| } |
| } |
| break |
| } |
| } |
|
|
| |
| if (cacheableContent) { |
| const hash = crypto |
| .createHash('sha256') |
| .update(cacheableContent) |
| .digest('hex') |
| .substring(0, 32) |
| logger.debug(`📋 Session hash generated from cacheable content: ${hash}`) |
| return hash |
| } |
|
|
| |
| if (system) { |
| let systemText = '' |
| if (typeof system === 'string') { |
| systemText = system |
| } else if (Array.isArray(system)) { |
| systemText = system.map((part) => part.text || '').join('') |
| } |
|
|
| if (systemText) { |
| const hash = crypto.createHash('sha256').update(systemText).digest('hex').substring(0, 32) |
| logger.debug(`📋 Session hash generated from system content: ${hash}`) |
| return hash |
| } |
| } |
|
|
| |
| if (messages.length > 0) { |
| const firstMessage = messages[0] |
| let firstMessageText = '' |
|
|
| if (typeof firstMessage.content === 'string') { |
| firstMessageText = firstMessage.content |
| } else if (Array.isArray(firstMessage.content)) { |
| if (!firstMessage.content) { |
| logger.error('📋 Session hash generated from first message failed: ', firstMessage) |
| } |
|
|
| firstMessageText = firstMessage.content |
| .filter((part) => part.type === 'text') |
| .map((part) => part.text || '') |
| .join('') |
| } |
|
|
| if (firstMessageText) { |
| const hash = crypto |
| .createHash('sha256') |
| .update(firstMessageText) |
| .digest('hex') |
| .substring(0, 32) |
| logger.debug(`📋 Session hash generated from first message: ${hash}`) |
| return hash |
| } |
| } |
|
|
| |
| logger.debug('📋 Unable to generate session hash - no suitable content found') |
| return null |
| } |
|
|
| |
| |
| |
| |
| |
| getSessionRedisKey(sessionHash) { |
| return `sticky_session:${sessionHash}` |
| } |
|
|
| |
| |
| |
| |
| |
| isValidSessionHash(sessionHash) { |
| return ( |
| typeof sessionHash === 'string' && |
| sessionHash.length === 32 && |
| /^[a-f0-9]{32}$/.test(sessionHash) |
| ) |
| } |
| } |
|
|
| module.exports = new SessionHelper() |
|
|