mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-25 11:20:07 +08:00
♻️ refactor: rename SessionLog to SessionMessage for semantic clarity
- Rename SessionLogEntity → SessionMessageEntity type definition - Rename SessionLogService → SessionMessageService with all methods - Rename API routes /logs → /messages for better REST semantics - Update database queries and service layer naming - Update all Swagger documentation and validation middleware - Maintain backward compatibility in database schema This improves code readability by using more accurate terminology for conversational message data rather than generic "log" naming.
This commit is contained in:
parent
a4bb82a02d
commit
c785be82dd
@ -10,7 +10,7 @@ import { agentsRoutes } from './routes/agents'
|
||||
import { chatRoutes } from './routes/chat'
|
||||
import { mcpRoutes } from './routes/mcp'
|
||||
import { modelsRoutes } from './routes/models'
|
||||
import { sessionLogsRoutes } from './routes/session-logs'
|
||||
import { sessionMessagesRoutes } from './routes/session-messages'
|
||||
import { sessionsRoutes } from './routes/sessions'
|
||||
|
||||
const logger = loggerService.withContext('ApiServer')
|
||||
@ -125,7 +125,7 @@ apiRouter.use('/mcps', mcpRoutes)
|
||||
apiRouter.use('/models', modelsRoutes)
|
||||
apiRouter.use('/agents', agentsRoutes)
|
||||
apiRouter.use('/sessions', sessionsRoutes)
|
||||
apiRouter.use('/', sessionLogsRoutes) // This handles /sessions/:sessionId/logs and /session-logs/:logId
|
||||
apiRouter.use('/', sessionMessagesRoutes) // This handles /sessions/:sessionId/messages and /session-messages/:messageId
|
||||
app.use('/v1', apiRouter)
|
||||
|
||||
// Setup OpenAPI documentation
|
||||
|
||||
@ -551,14 +551,14 @@ router.delete('/:agentId', validateAgentId, handleValidationErrors, async (req:
|
||||
})
|
||||
|
||||
// Mount session routes as nested resources
|
||||
import { createSessionLogsRouter } from './session-logs'
|
||||
import { createSessionMessagesRouter } from './session-messages'
|
||||
import { createSessionsRouter } from './sessions'
|
||||
|
||||
const sessionsRouter = createSessionsRouter()
|
||||
const sessionLogsRouter = createSessionLogsRouter()
|
||||
const sessionMessagesRouter = createSessionMessagesRouter()
|
||||
|
||||
// Mount nested routes
|
||||
router.use('/:agentId/sessions', sessionsRouter)
|
||||
router.use('/:agentId/sessions/:sessionId/logs', sessionLogsRouter)
|
||||
router.use('/:agentId/sessions/:sessionId/messages', sessionMessagesRouter)
|
||||
|
||||
export { router as agentsRoutes }
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import express, { Request, Response } from 'express'
|
||||
import { body, param, query, validationResult } from 'express-validator'
|
||||
|
||||
import { agentService, sessionLogService, sessionService } from '../../services/agents'
|
||||
import { agentService, sessionMessageService, sessionService } from '../../services/agents'
|
||||
import { loggerService } from '../../services/LoggerService'
|
||||
|
||||
const logger = loggerService.withContext('ApiServerSessionLogsRoutes')
|
||||
const logger = loggerService.withContext('ApiServerSessionMessagesRoutes')
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
// Validation middleware
|
||||
const validateSessionLog = [
|
||||
const validateSessionMessage = [
|
||||
body('parent_id').optional().isInt({ min: 1 }).withMessage('Parent ID must be a positive integer'),
|
||||
body('role').notEmpty().isIn(['user', 'agent', 'system', 'tool']).withMessage('Valid role is required'),
|
||||
body('type').notEmpty().isString().withMessage('Type is required'),
|
||||
@ -17,12 +17,12 @@ const validateSessionLog = [
|
||||
body('metadata').optional().isObject().withMessage('Metadata must be a valid object')
|
||||
]
|
||||
|
||||
const validateSessionLogUpdate = [
|
||||
const validateSessionMessageUpdate = [
|
||||
body('content').optional().isObject().withMessage('Content must be a valid object'),
|
||||
body('metadata').optional().isObject().withMessage('Metadata must be a valid object')
|
||||
]
|
||||
|
||||
const validateBulkSessionLogs = [
|
||||
const validateBulkSessionMessages = [
|
||||
body().isArray().withMessage('Request body must be an array'),
|
||||
body('*.parent_id').optional().isInt({ min: 1 }).withMessage('Parent ID must be a positive integer'),
|
||||
body('*.role').notEmpty().isIn(['user', 'agent', 'system', 'tool']).withMessage('Valid role is required'),
|
||||
@ -35,7 +35,7 @@ const validateAgentId = [param('agentId').notEmpty().withMessage('Agent ID is re
|
||||
|
||||
const validateSessionId = [param('sessionId').notEmpty().withMessage('Session ID is required')]
|
||||
|
||||
const validateLogId = [param('logId').isInt({ min: 1 }).withMessage('Log ID must be a positive integer')]
|
||||
const validateMessageId = [param('messageId').isInt({ min: 1 }).withMessage('Message ID must be a positive integer')]
|
||||
|
||||
const validatePagination = [
|
||||
query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('Limit must be between 1 and 100'),
|
||||
@ -116,28 +116,28 @@ const checkAgentAndSessionExist = async (req: Request, res: Response, next: any)
|
||||
* @swagger
|
||||
* components:
|
||||
* schemas:
|
||||
* SessionLogEntity:
|
||||
* SessionMessageEntity:
|
||||
* type: object
|
||||
* properties:
|
||||
* id:
|
||||
* type: integer
|
||||
* description: Unique log entry identifier
|
||||
* description: Unique message entry identifier
|
||||
* session_id:
|
||||
* type: string
|
||||
* description: Reference to session
|
||||
* parent_id:
|
||||
* type: integer
|
||||
* description: Parent log entry ID for tree structure
|
||||
* description: Parent message entry ID for tree structure
|
||||
* role:
|
||||
* type: string
|
||||
* enum: [user, agent, system, tool]
|
||||
* description: Role that created the log entry
|
||||
* description: Role that created the message entry
|
||||
* type:
|
||||
* type: string
|
||||
* description: Type of log entry
|
||||
* description: Type of message entry
|
||||
* content:
|
||||
* type: object
|
||||
* description: JSON structured log data
|
||||
* description: JSON structured message data
|
||||
* metadata:
|
||||
* type: object
|
||||
* description: Additional metadata
|
||||
@ -155,22 +155,22 @@ const checkAgentAndSessionExist = async (req: Request, res: Response, next: any)
|
||||
* - content
|
||||
* - created_at
|
||||
* - updated_at
|
||||
* CreateSessionLogRequest:
|
||||
* CreateSessionMessageRequest:
|
||||
* type: object
|
||||
* properties:
|
||||
* parent_id:
|
||||
* type: integer
|
||||
* description: Parent log entry ID for tree structure
|
||||
* description: Parent message entry ID for tree structure
|
||||
* role:
|
||||
* type: string
|
||||
* enum: [user, agent, system, tool]
|
||||
* description: Role that created the log entry
|
||||
* description: Role that created the message entry
|
||||
* type:
|
||||
* type: string
|
||||
* description: Type of log entry
|
||||
* description: Type of message entry
|
||||
* content:
|
||||
* type: object
|
||||
* description: JSON structured log data
|
||||
* description: JSON structured message data
|
||||
* metadata:
|
||||
* type: object
|
||||
* description: Additional metadata
|
||||
@ -180,17 +180,17 @@ const checkAgentAndSessionExist = async (req: Request, res: Response, next: any)
|
||||
* - content
|
||||
*/
|
||||
|
||||
// Create nested session logs router
|
||||
function createSessionLogsRouter(): express.Router {
|
||||
const sessionLogsRouter = express.Router({ mergeParams: true })
|
||||
// Create nested session messages router
|
||||
function createSessionMessagesRouter(): express.Router {
|
||||
const sessionMessagesRouter = express.Router({ mergeParams: true })
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/logs:
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/messages:
|
||||
* post:
|
||||
* summary: Create a new log entry for a session
|
||||
* description: Creates a new log entry for the specified session
|
||||
* tags: [Session Logs]
|
||||
* summary: Create a new message entry for a session
|
||||
* description: Creates a new message entry for the specified session
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: agentId
|
||||
@ -209,14 +209,14 @@ function createSessionLogsRouter(): express.Router {
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/CreateSessionLogRequest'
|
||||
* $ref: '#/components/schemas/CreateSessionMessageRequest'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Log entry created successfully
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* 400:
|
||||
* description: Validation error
|
||||
* content:
|
||||
@ -236,32 +236,32 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
sessionLogsRouter.post(
|
||||
sessionMessagesRouter.post(
|
||||
'/',
|
||||
validateAgentId,
|
||||
validateSessionId,
|
||||
checkAgentAndSessionExist,
|
||||
validateSessionLog,
|
||||
validateSessionMessage,
|
||||
handleValidationErrors,
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { sessionId } = req.params
|
||||
const logData = { ...req.body, session_id: sessionId }
|
||||
const messageData = { ...req.body, session_id: sessionId }
|
||||
|
||||
logger.info(`Creating new log entry for session: ${sessionId}`)
|
||||
logger.debug('Log data:', logData)
|
||||
logger.info(`Creating new message entry for session: ${sessionId}`)
|
||||
logger.debug('Message data:', messageData)
|
||||
|
||||
const log = await sessionLogService.createSessionLog(logData)
|
||||
const message = await sessionMessageService.createSessionMessage(messageData)
|
||||
|
||||
logger.info(`Log entry created successfully: ${log.id}`)
|
||||
return res.status(201).json(log)
|
||||
logger.info(`Message entry created successfully: ${message.id}`)
|
||||
return res.status(201).json(message)
|
||||
} catch (error: any) {
|
||||
logger.error('Error creating session log:', error)
|
||||
logger.error('Error creating session message:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to create log entry',
|
||||
message: 'Failed to create message entry',
|
||||
type: 'internal_error',
|
||||
code: 'log_creation_failed'
|
||||
code: 'message_creation_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -270,11 +270,11 @@ function createSessionLogsRouter(): express.Router {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/logs/bulk:
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/messages/bulk:
|
||||
* post:
|
||||
* summary: Create multiple log entries for a session
|
||||
* description: Creates multiple log entries for the specified session in a single request
|
||||
* tags: [Session Logs]
|
||||
* summary: Create multiple message entries for a session
|
||||
* description: Creates multiple message entries for the specified session in a single request
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: agentId
|
||||
@ -295,7 +295,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/CreateSessionLogRequest'
|
||||
* $ref: '#/components/schemas/CreateSessionMessageRequest'
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Log entries created successfully
|
||||
@ -307,10 +307,10 @@ function createSessionLogsRouter(): express.Router {
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* count:
|
||||
* type: integer
|
||||
* description: Number of log entries created
|
||||
* description: Number of message entries created
|
||||
* 400:
|
||||
* description: Validation error
|
||||
* content:
|
||||
@ -330,34 +330,34 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
sessionLogsRouter.post(
|
||||
sessionMessagesRouter.post(
|
||||
'/bulk',
|
||||
validateAgentId,
|
||||
validateSessionId,
|
||||
checkAgentAndSessionExist,
|
||||
validateBulkSessionLogs,
|
||||
validateBulkSessionMessages,
|
||||
handleValidationErrors,
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { sessionId } = req.params
|
||||
const logsData = req.body.map((logData: any) => ({ ...logData, session_id: sessionId }))
|
||||
const messagesData = req.body.map((messageData: any) => ({ ...messageData, session_id: sessionId }))
|
||||
|
||||
logger.info(`Creating ${logsData.length} log entries for session: ${sessionId}`)
|
||||
logger.info(`Creating ${messagesData.length} message entries for session: ${sessionId}`)
|
||||
|
||||
const logs = await sessionLogService.bulkCreateSessionLogs(logsData)
|
||||
const messages = await sessionMessageService.bulkCreateSessionMessages(messagesData)
|
||||
|
||||
logger.info(`${logs.length} log entries created successfully for session: ${sessionId}`)
|
||||
logger.info(`${messages.length} message entries created successfully for session: ${sessionId}`)
|
||||
return res.status(201).json({
|
||||
data: logs,
|
||||
count: logs.length
|
||||
data: messages,
|
||||
count: messages.length
|
||||
})
|
||||
} catch (error: any) {
|
||||
logger.error('Error creating bulk session logs:', error)
|
||||
logger.error('Error creating bulk session messages:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to create log entries',
|
||||
message: 'Failed to create message entries',
|
||||
type: 'internal_error',
|
||||
code: 'bulk_log_creation_failed'
|
||||
code: 'bulk_message_creation_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -366,11 +366,11 @@ function createSessionLogsRouter(): express.Router {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/logs:
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/messages:
|
||||
* get:
|
||||
* summary: List log entries for a session
|
||||
* description: Retrieves a paginated list of log entries for the specified session
|
||||
* tags: [Session Logs]
|
||||
* summary: List message entries for a session
|
||||
* description: Retrieves a paginated list of message entries for the specified session
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: agentId
|
||||
@ -391,17 +391,17 @@ function createSessionLogsRouter(): express.Router {
|
||||
* minimum: 1
|
||||
* maximum: 100
|
||||
* default: 50
|
||||
* description: Number of log entries to return
|
||||
* description: Number of message entries to return
|
||||
* - in: query
|
||||
* name: offset
|
||||
* schema:
|
||||
* type: integer
|
||||
* minimum: 0
|
||||
* default: 0
|
||||
* description: Number of log entries to skip
|
||||
* description: Number of message entries to skip
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of log entries
|
||||
* description: List of message entries
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
@ -410,16 +410,16 @@ function createSessionLogsRouter(): express.Router {
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* total:
|
||||
* type: integer
|
||||
* description: Total number of log entries
|
||||
* description: Total number of message entries
|
||||
* limit:
|
||||
* type: integer
|
||||
* description: Number of log entries returned
|
||||
* description: Number of message entries returned
|
||||
* offset:
|
||||
* type: integer
|
||||
* description: Number of log entries skipped
|
||||
* description: Number of message entries skipped
|
||||
* 400:
|
||||
* description: Validation error
|
||||
* content:
|
||||
@ -439,7 +439,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
sessionLogsRouter.get(
|
||||
sessionMessagesRouter.get(
|
||||
'/',
|
||||
validateAgentId,
|
||||
validateSessionId,
|
||||
@ -452,24 +452,24 @@ function createSessionLogsRouter(): express.Router {
|
||||
const limit = req.query.limit ? parseInt(req.query.limit as string) : 50
|
||||
const offset = req.query.offset ? parseInt(req.query.offset as string) : 0
|
||||
|
||||
logger.info(`Listing logs for session: ${sessionId} with limit=${limit}, offset=${offset}`)
|
||||
logger.info(`Listing messages for session: ${sessionId} with limit=${limit}, offset=${offset}`)
|
||||
|
||||
const result = await sessionLogService.listSessionLogs(sessionId, { limit, offset })
|
||||
const result = await sessionMessageService.listSessionMessages(sessionId, { limit, offset })
|
||||
|
||||
logger.info(`Retrieved ${result.logs.length} logs (total: ${result.total}) for session: ${sessionId}`)
|
||||
logger.info(`Retrieved ${result.messages.length} messages (total: ${result.total}) for session: ${sessionId}`)
|
||||
return res.json({
|
||||
data: result.logs,
|
||||
data: result.messages,
|
||||
total: result.total,
|
||||
limit,
|
||||
offset
|
||||
})
|
||||
} catch (error: any) {
|
||||
logger.error('Error listing session logs:', error)
|
||||
logger.error('Error listing session messages:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to list log entries',
|
||||
message: 'Failed to list message entries',
|
||||
type: 'internal_error',
|
||||
code: 'log_list_failed'
|
||||
code: 'message_list_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -478,11 +478,11 @@ function createSessionLogsRouter(): express.Router {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/logs/{logId}:
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/messages/{messageId}:
|
||||
* get:
|
||||
* summary: Get log entry by ID
|
||||
* description: Retrieves a specific log entry for the specified session
|
||||
* tags: [Session Logs]
|
||||
* summary: Get message entry by ID
|
||||
* description: Retrieves a specific message entry for the specified session
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: agentId
|
||||
@ -497,7 +497,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* type: string
|
||||
* description: Session ID
|
||||
* - in: path
|
||||
* name: logId
|
||||
* name: messageId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
@ -508,9 +508,9 @@ function createSessionLogsRouter(): express.Router {
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* 404:
|
||||
* description: Agent, session, or log entry not found
|
||||
* description: Agent, session, or message entry not found
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
@ -522,54 +522,54 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
sessionLogsRouter.get(
|
||||
'/:logId',
|
||||
sessionMessagesRouter.get(
|
||||
'/:messageId',
|
||||
validateAgentId,
|
||||
validateSessionId,
|
||||
validateLogId,
|
||||
validateMessageId,
|
||||
checkAgentAndSessionExist,
|
||||
handleValidationErrors,
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { sessionId, logId } = req.params
|
||||
const logIdNum = parseInt(logId)
|
||||
const { sessionId, messageId } = req.params
|
||||
const messageIdNum = parseInt(messageId)
|
||||
|
||||
logger.info(`Getting log entry: ${logId} for session: ${sessionId}`)
|
||||
logger.info(`Getting message entry: ${messageId} for session: ${sessionId}`)
|
||||
|
||||
const log = await sessionLogService.getSessionLog(logIdNum)
|
||||
const message = await sessionMessageService.getSessionMessage(messageIdNum)
|
||||
|
||||
if (!log) {
|
||||
logger.warn(`Log entry not found: ${logId}`)
|
||||
if (!message) {
|
||||
logger.warn(`Message entry not found: ${messageId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found',
|
||||
message: 'Message entry not found',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Verify log belongs to the session
|
||||
if (log.session_id !== sessionId) {
|
||||
logger.warn(`Log entry ${logId} does not belong to session ${sessionId}`)
|
||||
// Verify message belongs to the session
|
||||
if (message.session_id !== sessionId) {
|
||||
logger.warn(`Message entry ${messageId} does not belong to session ${sessionId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found for this session',
|
||||
message: 'Message entry not found for this session',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Log entry retrieved successfully: ${logId}`)
|
||||
return res.json(log)
|
||||
logger.info(`Message entry retrieved successfully: ${messageId}`)
|
||||
return res.json(message)
|
||||
} catch (error: any) {
|
||||
logger.error('Error getting session log:', error)
|
||||
logger.error('Error getting session message:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to get log entry',
|
||||
message: 'Failed to get message entry',
|
||||
type: 'internal_error',
|
||||
code: 'log_get_failed'
|
||||
code: 'message_get_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -578,11 +578,11 @@ function createSessionLogsRouter(): express.Router {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/logs/{logId}:
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/messages/{messageId}:
|
||||
* put:
|
||||
* summary: Update log entry
|
||||
* description: Updates an existing log entry for the specified session
|
||||
* tags: [Session Logs]
|
||||
* summary: Update message entry
|
||||
* description: Updates an existing message entry for the specified session
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: agentId
|
||||
@ -597,7 +597,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* type: string
|
||||
* description: Session ID
|
||||
* - in: path
|
||||
* name: logId
|
||||
* name: messageId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
@ -611,7 +611,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* properties:
|
||||
* content:
|
||||
* type: object
|
||||
* description: Updated log content
|
||||
* description: Updated message content
|
||||
* metadata:
|
||||
* type: object
|
||||
* description: Updated metadata
|
||||
@ -621,7 +621,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* 400:
|
||||
* description: Validation error
|
||||
* content:
|
||||
@ -629,7 +629,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
* 404:
|
||||
* description: Agent, session, or log entry not found
|
||||
* description: Agent, session, or message entry not found
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
@ -641,57 +641,57 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
sessionLogsRouter.put(
|
||||
'/:logId',
|
||||
sessionMessagesRouter.put(
|
||||
'/:messageId',
|
||||
validateAgentId,
|
||||
validateSessionId,
|
||||
validateLogId,
|
||||
validateMessageId,
|
||||
checkAgentAndSessionExist,
|
||||
validateSessionLogUpdate,
|
||||
validateSessionMessageUpdate,
|
||||
handleValidationErrors,
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { sessionId, logId } = req.params
|
||||
const logIdNum = parseInt(logId)
|
||||
const { sessionId, messageId } = req.params
|
||||
const messageIdNum = parseInt(messageId)
|
||||
|
||||
logger.info(`Updating log entry: ${logId} for session: ${sessionId}`)
|
||||
logger.info(`Updating message entry: ${messageId} for session: ${sessionId}`)
|
||||
logger.debug('Update data:', req.body)
|
||||
|
||||
// First check if log exists and belongs to session
|
||||
const existingLog = await sessionLogService.getSessionLog(logIdNum)
|
||||
if (!existingLog || existingLog.session_id !== sessionId) {
|
||||
logger.warn(`Log entry ${logId} not found for session ${sessionId}`)
|
||||
const existingMessage = await sessionMessageService.getSessionMessage(messageIdNum)
|
||||
if (!existingMessage || existingMessage.session_id !== sessionId) {
|
||||
logger.warn(`Log entry ${messageId} not found for session ${sessionId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found for this session',
|
||||
message: 'Message entry not found for this session',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const log = await sessionLogService.updateSessionLog(logIdNum, req.body)
|
||||
const message = await sessionMessageService.updateSessionMessage(messageIdNum, req.body)
|
||||
|
||||
if (!log) {
|
||||
logger.warn(`Log entry not found for update: ${logId}`)
|
||||
if (!message) {
|
||||
logger.warn(`Log entry not found for update: ${messageId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found',
|
||||
message: 'Message entry not found',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Log entry updated successfully: ${logId}`)
|
||||
return res.json(log)
|
||||
logger.info(`Log entry updated successfully: ${messageId}`)
|
||||
return res.json(message)
|
||||
} catch (error: any) {
|
||||
logger.error('Error updating session log:', error)
|
||||
logger.error('Error updating session message:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to update log entry',
|
||||
message: 'Failed to update message entry',
|
||||
type: 'internal_error',
|
||||
code: 'log_update_failed'
|
||||
code: 'message_update_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -700,11 +700,11 @@ function createSessionLogsRouter(): express.Router {
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/logs/{logId}:
|
||||
* /v1/agents/{agentId}/sessions/{sessionId}/messages/{messageId}:
|
||||
* delete:
|
||||
* summary: Delete log entry
|
||||
* description: Deletes a specific log entry
|
||||
* tags: [Session Logs]
|
||||
* summary: Delete message entry
|
||||
* description: Deletes a specific message entry
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: agentId
|
||||
@ -719,7 +719,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* type: string
|
||||
* description: Session ID
|
||||
* - in: path
|
||||
* name: logId
|
||||
* name: messageId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
@ -728,7 +728,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* 204:
|
||||
* description: Log entry deleted successfully
|
||||
* 404:
|
||||
* description: Agent, session, or log entry not found
|
||||
* description: Agent, session, or message entry not found
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
@ -740,72 +740,72 @@ function createSessionLogsRouter(): express.Router {
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
sessionLogsRouter.delete(
|
||||
'/:logId',
|
||||
sessionMessagesRouter.delete(
|
||||
'/:messageId',
|
||||
validateAgentId,
|
||||
validateSessionId,
|
||||
validateLogId,
|
||||
validateMessageId,
|
||||
checkAgentAndSessionExist,
|
||||
handleValidationErrors,
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { sessionId, logId } = req.params
|
||||
const logIdNum = parseInt(logId)
|
||||
const { sessionId, messageId } = req.params
|
||||
const messageIdNum = parseInt(messageId)
|
||||
|
||||
logger.info(`Deleting log entry: ${logId} for session: ${sessionId}`)
|
||||
logger.info(`Deleting message entry: ${messageId} for session: ${sessionId}`)
|
||||
|
||||
// First check if log exists and belongs to session
|
||||
const existingLog = await sessionLogService.getSessionLog(logIdNum)
|
||||
if (!existingLog || existingLog.session_id !== sessionId) {
|
||||
logger.warn(`Log entry ${logId} not found for session ${sessionId}`)
|
||||
const existingMessage = await sessionMessageService.getSessionMessage(messageIdNum)
|
||||
if (!existingMessage || existingMessage.session_id !== sessionId) {
|
||||
logger.warn(`Log entry ${messageId} not found for session ${sessionId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found for this session',
|
||||
message: 'Message entry not found for this session',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const deleted = await sessionLogService.deleteSessionLog(logIdNum)
|
||||
const deleted = await sessionMessageService.deleteSessionMessage(messageIdNum)
|
||||
|
||||
if (!deleted) {
|
||||
logger.warn(`Log entry not found for deletion: ${logId}`)
|
||||
logger.warn(`Log entry not found for deletion: ${messageId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found',
|
||||
message: 'Message entry not found',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Log entry deleted successfully: ${logId}`)
|
||||
logger.info(`Log entry deleted successfully: ${messageId}`)
|
||||
return res.status(204).send()
|
||||
} catch (error: any) {
|
||||
logger.error('Error deleting session log:', error)
|
||||
logger.error('Error deleting session message:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to delete log entry',
|
||||
message: 'Failed to delete message entry',
|
||||
type: 'internal_error',
|
||||
code: 'log_delete_failed'
|
||||
code: 'message_delete_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return sessionLogsRouter
|
||||
return sessionMessagesRouter
|
||||
}
|
||||
|
||||
// Convenience routes (standalone session logs without agent context)
|
||||
// Convenience routes (standalone session messages without agent context)
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/sessions/{sessionId}/logs:
|
||||
* /v1/sessions/{sessionId}/messages:
|
||||
* get:
|
||||
* summary: List log entries for a session (convenience endpoint)
|
||||
* description: Retrieves a paginated list of log entries for the specified session without requiring agent context
|
||||
* tags: [Session Logs]
|
||||
* summary: List message entries for a session (convenience endpoint)
|
||||
* description: Retrieves a paginated list of message entries for the specified session without requiring agent context
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: sessionId
|
||||
@ -820,17 +820,17 @@ function createSessionLogsRouter(): express.Router {
|
||||
* minimum: 1
|
||||
* maximum: 100
|
||||
* default: 50
|
||||
* description: Number of log entries to return
|
||||
* description: Number of message entries to return
|
||||
* - in: query
|
||||
* name: offset
|
||||
* schema:
|
||||
* type: integer
|
||||
* minimum: 0
|
||||
* default: 0
|
||||
* description: Number of log entries to skip
|
||||
* description: Number of message entries to skip
|
||||
* responses:
|
||||
* 200:
|
||||
* description: List of log entries
|
||||
* description: List of message entries
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
@ -839,16 +839,16 @@ function createSessionLogsRouter(): express.Router {
|
||||
* data:
|
||||
* type: array
|
||||
* items:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* total:
|
||||
* type: integer
|
||||
* description: Total number of log entries
|
||||
* description: Total number of message entries
|
||||
* limit:
|
||||
* type: integer
|
||||
* description: Number of log entries returned
|
||||
* description: Number of message entries returned
|
||||
* offset:
|
||||
* type: integer
|
||||
* description: Number of log entries skipped
|
||||
* description: Number of message entries skipped
|
||||
* 400:
|
||||
* description: Validation error
|
||||
* content:
|
||||
@ -869,7 +869,7 @@ function createSessionLogsRouter(): express.Router {
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
router.get(
|
||||
'/:sessionId/logs',
|
||||
'/:sessionId/messages',
|
||||
validateSessionId,
|
||||
validatePagination,
|
||||
handleValidationErrors,
|
||||
@ -891,24 +891,24 @@ router.get(
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Listing logs for session: ${sessionId} with limit=${limit}, offset=${offset}`)
|
||||
logger.info(`Listing messages for session: ${sessionId} with limit=${limit}, offset=${offset}`)
|
||||
|
||||
const result = await sessionLogService.listSessionLogs(sessionId, { limit, offset })
|
||||
const result = await sessionMessageService.listSessionMessages(sessionId, { limit, offset })
|
||||
|
||||
logger.info(`Retrieved ${result.logs.length} logs (total: ${result.total}) for session: ${sessionId}`)
|
||||
logger.info(`Retrieved ${result.messages.length} messages (total: ${result.total}) for session: ${sessionId}`)
|
||||
return res.json({
|
||||
data: result.logs,
|
||||
data: result.messages,
|
||||
total: result.total,
|
||||
limit,
|
||||
offset
|
||||
})
|
||||
} catch (error: any) {
|
||||
logger.error('Error listing session logs:', error)
|
||||
logger.error('Error listing session messages:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to list log entries',
|
||||
message: 'Failed to list message entries',
|
||||
type: 'internal_error',
|
||||
code: 'log_list_failed'
|
||||
code: 'message_list_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -917,14 +917,14 @@ router.get(
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /v1/session-logs/{logId}:
|
||||
* /v1/session-messages/{messageId}:
|
||||
* get:
|
||||
* summary: Get log entry by ID (convenience endpoint)
|
||||
* description: Retrieves a specific log entry without requiring agent or session context
|
||||
* tags: [Session Logs]
|
||||
* summary: Get message entry by ID (convenience endpoint)
|
||||
* description: Retrieves a specific message entry without requiring agent or session context
|
||||
* tags: [Session Messages]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: logId
|
||||
* name: messageId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: integer
|
||||
@ -935,7 +935,7 @@ router.get(
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/SessionLogEntity'
|
||||
* $ref: '#/components/schemas/SessionMessageEntity'
|
||||
* 404:
|
||||
* description: Log entry not found
|
||||
* content:
|
||||
@ -949,38 +949,43 @@ router.get(
|
||||
* schema:
|
||||
* $ref: '#/components/schemas/Error'
|
||||
*/
|
||||
router.get('/session-logs/:logId', validateLogId, handleValidationErrors, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { logId } = req.params
|
||||
const logIdNum = parseInt(logId)
|
||||
router.get(
|
||||
'/session-messages/:messageId',
|
||||
validateMessageId,
|
||||
handleValidationErrors,
|
||||
async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { messageId } = req.params
|
||||
const messageIdNum = parseInt(messageId)
|
||||
|
||||
logger.info(`Getting log entry: ${logId}`)
|
||||
logger.info(`Getting message entry: ${messageId}`)
|
||||
|
||||
const log = await sessionLogService.getSessionLog(logIdNum)
|
||||
const message = await sessionMessageService.getSessionMessage(messageIdNum)
|
||||
|
||||
if (!log) {
|
||||
logger.warn(`Log entry not found: ${logId}`)
|
||||
return res.status(404).json({
|
||||
if (!message) {
|
||||
logger.warn(`Log entry not found: ${messageId}`)
|
||||
return res.status(404).json({
|
||||
error: {
|
||||
message: 'Log entry not found',
|
||||
type: 'not_found',
|
||||
code: 'message_not_found'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Log entry retrieved successfully: ${messageId}`)
|
||||
return res.json(message)
|
||||
} catch (error: any) {
|
||||
logger.error('Error getting session message:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Log entry not found',
|
||||
type: 'not_found',
|
||||
code: 'log_not_found'
|
||||
message: 'Failed to get message entry',
|
||||
type: 'internal_error',
|
||||
code: 'message_get_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Log entry retrieved successfully: ${logId}`)
|
||||
return res.json(log)
|
||||
} catch (error: any) {
|
||||
logger.error('Error getting session log:', error)
|
||||
return res.status(500).json({
|
||||
error: {
|
||||
message: 'Failed to get log entry',
|
||||
type: 'internal_error',
|
||||
code: 'log_get_failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
export { createSessionLogsRouter, router as sessionLogsRoutes }
|
||||
export { createSessionMessagesRouter, router as sessionMessagesRoutes }
|
||||
@ -16,7 +16,7 @@ export { Migrator } from './migrator'
|
||||
// Database queries (organized by entity)
|
||||
export * as AgentQueries from './queries/agent.queries'
|
||||
export * as SessionQueries from './queries/session.queries'
|
||||
export * as SessionLogQueries from './queries/sessionLog.queries'
|
||||
export * as SessionMessageQueries from './queries/sessionMessage.queries'
|
||||
|
||||
// Migration schema utilities (for migration tracking table)
|
||||
export * as MigrationsSchema from './schema/migrations'
|
||||
@ -25,7 +25,7 @@ export * as MigrationsSchema from './schema/migrations'
|
||||
// Services only use the query methods, not the table/index creation methods
|
||||
import * as AgentQueriesActual from './queries/agent.queries'
|
||||
import * as SessionQueriesActual from './queries/session.queries'
|
||||
import * as SessionLogQueriesActual from './queries/sessionLog.queries'
|
||||
import * as SessionMessageQueriesActual from './queries/sessionMessage.queries'
|
||||
|
||||
export const AgentQueries_Legacy = {
|
||||
// Agent operations
|
||||
@ -34,6 +34,6 @@ export const AgentQueries_Legacy = {
|
||||
// Session operations
|
||||
sessions: SessionQueriesActual.SessionQueries,
|
||||
|
||||
// Session logs operations
|
||||
sessionLogs: SessionLogQueriesActual.SessionLogQueries
|
||||
// Session messages operations
|
||||
sessionMessages: SessionMessageQueriesActual.SessionMessageQueries
|
||||
}
|
||||
|
||||
@ -4,4 +4,4 @@
|
||||
|
||||
export { AgentQueries } from './agent.queries'
|
||||
export { SessionQueries } from './session.queries'
|
||||
export { SessionLogQueries } from './sessionLog.queries'
|
||||
export { SessionMessageQueries } from './sessionMessage.queries'
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* SQL queries for Session Log operations
|
||||
* SQL queries for Session Message operations
|
||||
*/
|
||||
|
||||
export const SessionLogQueries = {
|
||||
export const SessionMessageQueries = {
|
||||
// CREATE
|
||||
insert: `
|
||||
INSERT INTO session_logs (session_id, parent_id, role, type, content, metadata, created_at, updated_at)
|
||||
@ -1,12 +1,12 @@
|
||||
import { loggerService } from '@logger'
|
||||
import type { SessionLogEntity } from '@types'
|
||||
import type { SessionMessageEntity } from '@types'
|
||||
|
||||
import { BaseService } from '../BaseService'
|
||||
import { AgentQueries_Legacy as AgentQueries } from '../database'
|
||||
|
||||
const logger = loggerService.withContext('SessionLogService')
|
||||
const logger = loggerService.withContext('SessionMessageService')
|
||||
|
||||
export interface CreateSessionLogRequest {
|
||||
export interface CreateSessionMessageRequest {
|
||||
session_id: string
|
||||
parent_id?: number
|
||||
role: 'user' | 'agent' | 'system' | 'tool'
|
||||
@ -15,31 +15,31 @@ export interface CreateSessionLogRequest {
|
||||
metadata?: Record<string, any>
|
||||
}
|
||||
|
||||
export interface UpdateSessionLogRequest {
|
||||
export interface UpdateSessionMessageRequest {
|
||||
content?: Record<string, any>
|
||||
metadata?: Record<string, any>
|
||||
}
|
||||
|
||||
export interface ListSessionLogsOptions {
|
||||
export interface ListSessionMessagesOptions {
|
||||
limit?: number
|
||||
offset?: number
|
||||
}
|
||||
|
||||
export class SessionLogService extends BaseService {
|
||||
private static instance: SessionLogService | null = null
|
||||
export class SessionMessageService extends BaseService {
|
||||
private static instance: SessionMessageService | null = null
|
||||
|
||||
static getInstance(): SessionLogService {
|
||||
if (!SessionLogService.instance) {
|
||||
SessionLogService.instance = new SessionLogService()
|
||||
static getInstance(): SessionMessageService {
|
||||
if (!SessionMessageService.instance) {
|
||||
SessionMessageService.instance = new SessionMessageService()
|
||||
}
|
||||
return SessionLogService.instance
|
||||
return SessionMessageService.instance
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
await BaseService.initialize()
|
||||
}
|
||||
|
||||
async createSessionLog(logData: CreateSessionLogRequest): Promise<SessionLogEntity> {
|
||||
async createSessionMessage(messageData: CreateSessionMessageRequest): Promise<SessionMessageEntity> {
|
||||
this.ensureInitialized()
|
||||
|
||||
// Validate session exists - we'll need to import SessionService for this check
|
||||
@ -47,52 +47,52 @@ export class SessionLogService extends BaseService {
|
||||
// The database foreign key constraint will handle this
|
||||
|
||||
// Validate parent exists if specified
|
||||
if (logData.parent_id) {
|
||||
const parentExists = await this.sessionLogExists(logData.parent_id)
|
||||
if (messageData.parent_id) {
|
||||
const parentExists = await this.sessionMessageExists(messageData.parent_id)
|
||||
if (!parentExists) {
|
||||
throw new Error(`Parent log with id ${logData.parent_id} does not exist`)
|
||||
throw new Error(`Parent message with id ${messageData.parent_id} does not exist`)
|
||||
}
|
||||
}
|
||||
|
||||
const now = new Date().toISOString()
|
||||
|
||||
const values = [
|
||||
logData.session_id,
|
||||
logData.parent_id || null,
|
||||
logData.role,
|
||||
logData.type,
|
||||
JSON.stringify(logData.content),
|
||||
logData.metadata ? JSON.stringify(logData.metadata) : null,
|
||||
messageData.session_id,
|
||||
messageData.parent_id || null,
|
||||
messageData.role,
|
||||
messageData.type,
|
||||
JSON.stringify(messageData.content),
|
||||
messageData.metadata ? JSON.stringify(messageData.metadata) : null,
|
||||
now,
|
||||
now
|
||||
]
|
||||
|
||||
const result = await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.insert,
|
||||
sql: AgentQueries.sessionMessages.insert,
|
||||
args: values
|
||||
})
|
||||
|
||||
if (!result.lastInsertRowid) {
|
||||
throw new Error('Failed to create session log')
|
||||
throw new Error('Failed to create session message')
|
||||
}
|
||||
|
||||
const logResult = await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.getById,
|
||||
sql: AgentQueries.sessionMessages.getById,
|
||||
args: [result.lastInsertRowid]
|
||||
})
|
||||
|
||||
if (!logResult.rows[0]) {
|
||||
throw new Error('Failed to retrieve created session log')
|
||||
throw new Error('Failed to retrieve created session message')
|
||||
}
|
||||
|
||||
return this.deserializeSessionLog(logResult.rows[0]) as SessionLogEntity
|
||||
return this.deserializeSessionMessage(logResult.rows[0]) as SessionMessageEntity
|
||||
}
|
||||
|
||||
async getSessionLog(id: number): Promise<SessionLogEntity | null> {
|
||||
async getSessionMessage(id: number): Promise<SessionMessageEntity | null> {
|
||||
this.ensureInitialized()
|
||||
|
||||
const result = await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.getById,
|
||||
sql: AgentQueries.sessionMessages.getById,
|
||||
args: [id]
|
||||
})
|
||||
|
||||
@ -100,28 +100,28 @@ export class SessionLogService extends BaseService {
|
||||
return null
|
||||
}
|
||||
|
||||
return this.deserializeSessionLog(result.rows[0]) as SessionLogEntity
|
||||
return this.deserializeSessionMessage(result.rows[0]) as SessionMessageEntity
|
||||
}
|
||||
|
||||
async listSessionLogs(
|
||||
async listSessionMessages(
|
||||
sessionId: string,
|
||||
options: ListSessionLogsOptions = {}
|
||||
): Promise<{ logs: SessionLogEntity[]; total: number }> {
|
||||
options: ListSessionMessagesOptions = {}
|
||||
): Promise<{ messages: SessionMessageEntity[]; total: number }> {
|
||||
this.ensureInitialized()
|
||||
|
||||
// Get total count
|
||||
const countResult = await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.countBySessionId,
|
||||
sql: AgentQueries.sessionMessages.countBySessionId,
|
||||
args: [sessionId]
|
||||
})
|
||||
const total = (countResult.rows[0] as any).total
|
||||
|
||||
// Get logs with pagination
|
||||
// Get messages with pagination
|
||||
let query: string
|
||||
const args: any[] = [sessionId]
|
||||
|
||||
if (options.limit !== undefined) {
|
||||
query = AgentQueries.sessionLogs.getBySessionIdWithPagination
|
||||
query = AgentQueries.sessionMessages.getBySessionIdWithPagination
|
||||
args.push(options.limit)
|
||||
|
||||
if (options.offset !== undefined) {
|
||||
@ -130,7 +130,7 @@ export class SessionLogService extends BaseService {
|
||||
args.push(0)
|
||||
}
|
||||
} else {
|
||||
query = AgentQueries.sessionLogs.getBySessionId
|
||||
query = AgentQueries.sessionMessages.getBySessionId
|
||||
}
|
||||
|
||||
const result = await this.database.execute({
|
||||
@ -138,16 +138,16 @@ export class SessionLogService extends BaseService {
|
||||
args: args
|
||||
})
|
||||
|
||||
const logs = result.rows.map((row) => this.deserializeSessionLog(row)) as SessionLogEntity[]
|
||||
const messages = result.rows.map((row) => this.deserializeSessionMessage(row)) as SessionMessageEntity[]
|
||||
|
||||
return { logs, total }
|
||||
return { messages, total }
|
||||
}
|
||||
|
||||
async updateSessionLog(id: number, updates: UpdateSessionLogRequest): Promise<SessionLogEntity | null> {
|
||||
async updateSessionMessage(id: number, updates: UpdateSessionMessageRequest): Promise<SessionMessageEntity | null> {
|
||||
this.ensureInitialized()
|
||||
|
||||
// Check if log exists
|
||||
const existing = await this.getSessionLog(id)
|
||||
// Check if message exists
|
||||
const existing = await this.getSessionMessage(id)
|
||||
if (!existing) {
|
||||
return null
|
||||
}
|
||||
@ -168,50 +168,50 @@ export class SessionLogService extends BaseService {
|
||||
]
|
||||
|
||||
await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.update,
|
||||
sql: AgentQueries.sessionMessages.update,
|
||||
args: values
|
||||
})
|
||||
|
||||
return await this.getSessionLog(id)
|
||||
return await this.getSessionMessage(id)
|
||||
}
|
||||
|
||||
async deleteSessionLog(id: number): Promise<boolean> {
|
||||
async deleteSessionMessage(id: number): Promise<boolean> {
|
||||
this.ensureInitialized()
|
||||
|
||||
const result = await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.deleteById,
|
||||
sql: AgentQueries.sessionMessages.deleteById,
|
||||
args: [id]
|
||||
})
|
||||
|
||||
return result.rowsAffected > 0
|
||||
}
|
||||
|
||||
async sessionLogExists(id: number): Promise<boolean> {
|
||||
async sessionMessageExists(id: number): Promise<boolean> {
|
||||
this.ensureInitialized()
|
||||
|
||||
const result = await this.database.execute({
|
||||
sql: AgentQueries.sessionLogs.getById,
|
||||
sql: AgentQueries.sessionMessages.getById,
|
||||
args: [id]
|
||||
})
|
||||
|
||||
return result.rows.length > 0
|
||||
}
|
||||
|
||||
async bulkCreateSessionLogs(logs: CreateSessionLogRequest[]): Promise<SessionLogEntity[]> {
|
||||
async bulkCreateSessionMessages(messages: CreateSessionMessageRequest[]): Promise<SessionMessageEntity[]> {
|
||||
this.ensureInitialized()
|
||||
|
||||
const results: SessionLogEntity[] = []
|
||||
const results: SessionMessageEntity[] = []
|
||||
|
||||
// Use a transaction for bulk insert
|
||||
for (const logData of logs) {
|
||||
const result = await this.createSessionLog(logData)
|
||||
for (const messageData of messages) {
|
||||
const result = await this.createSessionMessage(messageData)
|
||||
results.push(result)
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
private deserializeSessionLog(data: any): SessionLogEntity {
|
||||
private deserializeSessionMessage(data: any): SessionMessageEntity {
|
||||
if (!data) return data
|
||||
|
||||
const deserialized = { ...data }
|
||||
@ -238,4 +238,4 @@ export class SessionLogService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
export const sessionLogService = SessionLogService.getInstance()
|
||||
export const sessionMessageService = SessionMessageService.getInstance()
|
||||
@ -1,21 +1,25 @@
|
||||
/**
|
||||
* Agent Services Module
|
||||
*
|
||||
* This module provides service classes for managing agents, sessions, and session logs.
|
||||
* This module provides service classes for managing agents, sessions, and session messages.
|
||||
* All services extend BaseService and provide database operations with proper error handling.
|
||||
*/
|
||||
|
||||
// Service classes
|
||||
export { AgentService } from './AgentService'
|
||||
export { SessionLogService } from './SessionLogService'
|
||||
export { SessionMessageService } from './SessionMessageService'
|
||||
export { SessionService } from './SessionService'
|
||||
|
||||
// Service instances (singletons)
|
||||
export { agentService } from './AgentService'
|
||||
export { sessionLogService } from './SessionLogService'
|
||||
export { sessionMessageService } from './SessionMessageService'
|
||||
export { sessionService } from './SessionService'
|
||||
|
||||
// Type definitions for service requests and responses
|
||||
export type { CreateAgentRequest, ListAgentsOptions, UpdateAgentRequest } from './AgentService'
|
||||
export type { CreateSessionLogRequest, ListSessionLogsOptions, UpdateSessionLogRequest } from './SessionLogService'
|
||||
export type {
|
||||
CreateSessionMessageRequest,
|
||||
ListSessionMessagesOptions,
|
||||
UpdateSessionMessageRequest
|
||||
} from './SessionMessageService'
|
||||
export type { CreateSessionRequest, ListSessionsOptions, UpdateSessionRequest } from './SessionService'
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
/**
|
||||
* Database entity types for Agent, Session, and SessionLog
|
||||
* Database entity types for Agent, Session, and SessionMessage
|
||||
* Shared between main and renderer processes
|
||||
*/
|
||||
|
||||
export type SessionStatus = 'idle' | 'running' | 'completed' | 'failed' | 'stopped'
|
||||
export type PermissionMode = 'readOnly' | 'acceptEdits' | 'bypassPermissions'
|
||||
export type SessionLogRole = 'user' | 'agent' | 'system' | 'tool'
|
||||
export type SessionMessageRole = 'user' | 'agent' | 'system' | 'tool'
|
||||
export type AgentType = 'claude-code' | 'codex' | 'qwen-cli' | 'gemini-cli' | 'custom'
|
||||
|
||||
export type SessionLogType =
|
||||
export type SessionMessageType =
|
||||
| 'message' // User or agent message
|
||||
| 'thought' // Agent's internal reasoning/planning
|
||||
| 'action' // Tool/function call initiated
|
||||
@ -61,13 +61,13 @@ export interface AgentSessionEntity extends AgentConfiguration {
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
// SessionLog entity for tracking all agent activities
|
||||
export interface SessionLogEntity {
|
||||
// SessionMessage entity for tracking all agent activities
|
||||
export interface SessionMessageEntity {
|
||||
id: number // Auto-increment primary key
|
||||
session_id: string // Reference to session
|
||||
parent_id?: number // For tree structure (e.g., tool calls under an action)
|
||||
role: SessionLogRole // 'user', 'agent', 'system', 'tool'
|
||||
type: SessionLogType // Type of log entry
|
||||
role: SessionMessageRole // 'user', 'agent', 'system', 'tool'
|
||||
type: SessionMessageType // Type of log entry
|
||||
content: Record<string, any> // JSON structured data
|
||||
metadata?: Record<string, any> // Additional metadata (optional)
|
||||
created_at: string // ISO timestamp
|
||||
|
||||
Loading…
Reference in New Issue
Block a user