7.4 KiB
Overview
Implement comprehensive CRUD APIs for agent, agentSession, and agentSessionLogs management in Cherry Studio's API server using RESTful URL conventions.
Architecture Overview
- Service Layer
- Create AgentService class in src/main/services/agents/AgentService.ts
- Handles database operations using SQL queries from db.ts
- Manages SQLite database initialization and connections
- Provides business logic for agent operations
- API Routes
- Create route files in src/main/apiServer/routes/:
- agents.ts - Agent CRUD endpoints
- sessions.ts - Session CRUD endpoints
- session-logs.ts - Session logs CRUD endpoints
- Database Integration
- Use SQLite with @libsql/client (following MemoryService pattern)
- Database location: userData/agents.db
- Leverage existing SQL queries in src/main/services/agents/db.ts
Implementation Steps
Phase 1: Database Service Setup
- Create AgentService class with database initialization
- Implement database connection management
- Add database initialization to main process startup
- Create helper methods for JSON field serialization/deserialization
Phase 2: Agent CRUD Operations
- Implement service methods:
- createAgent(agent: Omit<AgentEntity, 'id' | 'created_at' | 'updated_at'>)
- getAgent(id: string)
- listAgents(options?: { limit?: number, offset?: number })
- updateAgent(id: string, updates: Partial)
- deleteAgent(id: string)
- Create API routes:
- POST /v1/agents - Create agent
- GET /v1/agents - List all agents
- GET /v1/agents/:agentId - Get agent by ID
- PUT /v1/agents/:agentId - Update agent
- DELETE /v1/agents/:agentId - Delete agent
Phase 3: Session CRUD Operations
- Implement service methods:
- createSession(session: Omit<AgentSessionEntity, 'id' | 'created_at' | 'updated_at'>)
- getSession(id: string)
- listSessions(agentId?: string, options?: { status?: SessionStatus, limit?: number, offset?: number })
- updateSession(id: string, updates: Partial)
- updateSessionStatus(id: string, status: SessionStatus)
- deleteSession(id: string)
- getSessionWithAgent(id: string) - Get session with merged agent configuration
- Create API routes (RESTful nested resources):
- POST /v1/agents/:agentId/sessions - Create session for specific agent
- GET /v1/agents/:agentId/sessions - List sessions for specific agent
- GET /v1/agents/:agentId/sessions/:sessionId - Get specific session
- PUT /v1/agents/:agentId/sessions/:sessionId - Update session
- PATCH /v1/agents/:agentId/sessions/:sessionId/status - Update session status
- DELETE /v1/agents/:agentId/sessions/:sessionId - Delete session
Additional convenience endpoints:
- GET /v1/sessions - List all sessions (across all agents)
- GET /v1/sessions/:sessionId - Get session by ID (without agent context)
Phase 4: Session Logs CRUD Operations
- Implement service methods:
- createSessionLog(log: Omit<SessionLogEntity, 'id' | 'created_at' | 'updated_at'>)
- getSessionLog(id: number)
- listSessionLogs(sessionId: string, options?: { limit?: number, offset?: number })
- updateSessionLog(id: number, updates: { content?: any, metadata?: any })
- deleteSessionLog(id: number)
- getSessionLogTree(sessionId: string) - Get logs with parent-child relationships
- bulkCreateSessionLogs(logs: Array<...>) - Batch insert logs
- Create API routes (RESTful nested resources):
- POST /v1/agents/:agentId/sessions/:sessionId/logs - Create log entry
- GET /v1/agents/:agentId/sessions/:sessionId/logs - List logs for session
- GET /v1/agents/:agentId/sessions/:sessionId/logs/:logId - Get specific log
- PUT /v1/agents/:agentId/sessions/:sessionId/logs/:logId - Update log
- DELETE /v1/agents/:agentId/sessions/:sessionId/logs/:logId - Delete log
- POST /v1/agents/:agentId/sessions/:sessionId/logs/bulk - Bulk create logs
Additional convenience endpoints:
- GET /v1/sessions/:sessionId/logs - Get logs without agent context
- GET /v1/session-logs/:logId - Get specific log by ID
Phase 5: Route Organization
- Mount routes with proper nesting: // In app.ts apiRouter.use('/agents', agentsRoutes) // agentsRoutes will handle: // - /agents/_ // - /agents/:agentId/sessions/_ // - /agents/:agentId/sessions/:sessionId/logs/*
// Convenience routes apiRouter.use('/sessions', sessionsRoutes) apiRouter.use('/session-logs', sessionLogsRoutes)
- Use Express Router mergeParams for nested routes: // In agents.ts const sessionsRouter = express.Router({ mergeParams: true }) router.use('/:agentId/sessions', sessionsRouter)
Phase 6: OpenAPI Documentation
- Add Swagger schemas for new entities:
- AgentEntity schema
- AgentSessionEntity schema
- SessionLogEntity schema
- Request/Response schemas
- Document all new endpoints with:
- Clear path parameters (agentId, sessionId, logId)
- Request body schemas
- Response examples
- Error responses
- Proper grouping by resource
Phase 7: Validation & Error Handling
- Add path parameter validation:
- Validate agentId exists before processing session requests
- Validate sessionId belongs to agentId
- Validate logId belongs to sessionId
- Implement middleware for:
- Request validation using express-validator
- Resource existence checks
- Permission validation (future consideration)
- Transaction support for complex operations
Phase 8: Testing
- Unit tests for service methods
- Integration tests for API endpoints
- Test nested resource validation
- Test cascading deletes
- Test transaction rollbacks
File Structure
src/ ├── main/ │ └── services/ │ └── agents/ │ ├── index.ts (existing) │ ├── db.ts (existing) │ └── AgentService.ts (new) ├── main/ │ └── apiServer/ │ └── routes/ │ ├── agents.ts (new - includes nested routes) │ ├── sessions.ts (new - convenience endpoints) │ └── session-logs.ts (new - convenience endpoints) └── renderer/ └── src/ └── types/ └── agent.ts (existing)
API Endpoint Summary
Agent Endpoints
- POST /v1/agents
- GET /v1/agents
- GET /v1/agents/:agentId
- PUT /v1/agents/:agentId
- DELETE /v1/agents/:agentId
Session Endpoints (RESTful)
- POST /v1/agents/:agentId/sessions
- GET /v1/agents/:agentId/sessions
- GET /v1/agents/:agentId/sessions/:sessionId
- PUT /v1/agents/:agentId/sessions/:sessionId
- PATCH /v1/agents/:agentId/sessions/:sessionId/status
- DELETE /v1/agents/:agentId/sessions/:sessionId
Session Convenience Endpoints
- GET /v1/sessions
- GET /v1/sessions/:sessionId
Session Log Endpoints (RESTful)
- POST /v1/agents/:agentId/sessions/:sessionId/logs
- GET /v1/agents/:agentId/sessions/:sessionId/logs
- GET /v1/agents/:agentId/sessions/:sessionId/logs/:logId
- PUT /v1/agents/:agentId/sessions/:sessionId/logs/:logId
- DELETE /v1/agents/:agentId/sessions/:sessionId/logs/:logId
- POST /v1/agents/:agentId/sessions/:sessionId/logs/bulk
Session Log Convenience Endpoints
- GET /v1/sessions/:sessionId/logs
- GET /v1/session-logs/:logId
Key Considerations
- Follow RESTful URL conventions with proper resource nesting
- Validate parent-child relationships in nested routes
- Use Express Router with mergeParams for nested routing
- Implement proper cascading deletes
- Add transaction support for data consistency
- Follow existing patterns from MemoryService
- Ensure backward compatibility
- Add rate limiting for write operations
Dependencies
- @libsql/client - SQLite database client
- express-validator - Request validation
- swagger-jsdoc - API documentation
- Existing types from @types/agent.ts