From d13c25444cec2d1a69943bb58ea0b0a91c6f2447 Mon Sep 17 00:00:00 2001 From: Vaayne Date: Fri, 19 Sep 2025 12:55:58 +0800 Subject: [PATCH] feat(agents, sessions): enhance agent and session schemas with detailed properties and CRUD API documentation --- src/main/apiServer/routes/agents/index.ts | 901 +++++++++++++++++++--- 1 file changed, 804 insertions(+), 97 deletions(-) diff --git a/src/main/apiServer/routes/agents/index.ts b/src/main/apiServer/routes/agents/index.ts index 4bd249b474..5d3393dc12 100644 --- a/src/main/apiServer/routes/agents/index.ts +++ b/src/main/apiServer/routes/agents/index.ts @@ -22,76 +22,114 @@ const agentsRouter = express.Router() * @swagger * components: * schemas: + * PermissionMode: + * type: string + * enum: [default, acceptEdits, bypassPermissions, plan] + * description: Permission mode for agent operations + * + * AgentType: + * type: string + * enum: [claude-code] + * description: Type of agent + * + * AgentConfiguration: + * type: object + * properties: + * permission_mode: + * $ref: '#/components/schemas/PermissionMode' + * default: default + * max_turns: + * type: integer + * default: 10 + * description: Maximum number of interaction turns + * additionalProperties: true + * + * AgentBase: + * type: object + * properties: + * name: + * type: string + * description: Agent name + * description: + * type: string + * description: Agent description + * accessible_paths: + * type: array + * items: + * type: string + * description: Array of directory paths the agent can access + * instructions: + * type: string + * description: System prompt/instructions + * model: + * type: string + * description: Main model ID + * plan_model: + * type: string + * description: Optional planning model ID + * small_model: + * type: string + * description: Optional small/fast model ID + * mcps: + * type: array + * items: + * type: string + * description: Array of MCP tool IDs + * allowed_tools: + * type: array + * items: + * type: string + * description: Array of allowed tool IDs (whitelist) + * configuration: + * $ref: '#/components/schemas/AgentConfiguration' + * required: + * - model + * - accessible_paths + * * AgentEntity: - * type: object - * properties: - * id: - * type: string - * description: Unique agent identifier - * name: - * type: string - * description: Agent name - * description: - * type: string - * description: Agent description - * avatar: - * type: string - * description: Agent avatar URL - * instructions: - * type: string - * description: System prompt/instructions - * model: - * type: string - * description: Main model ID - * plan_model: - * type: string - * description: Optional planning model ID - * small_model: - * type: string - * description: Optional small/fast model ID - * built_in_tools: - * type: array - * items: - * type: string - * description: Built-in tool IDs - * mcps: - * type: array - * items: - * type: string - * description: MCP tool IDs - * knowledges: - * type: array - * items: - * type: string - * description: Knowledge base IDs - * configuration: - * type: object - * description: Extensible settings - * accessible_paths: - * type: array - * items: - * type: string - * description: Accessible directory paths - * permission_mode: - * type: string - * enum: [readOnly, acceptEdits, bypassPermissions] - * description: Permission mode - * max_steps: - * type: integer - * description: Maximum steps the agent can take - * created_at: - * type: string - * format: date-time - * updated_at: - * type: string - * format: date-time - * required: - * - id - * - name - * - model - * - created_at - * - updated_at + * allOf: + * - $ref: '#/components/schemas/AgentBase' + * - type: object + * properties: + * id: + * type: string + * description: Unique agent identifier + * type: + * $ref: '#/components/schemas/AgentType' + * created_at: + * type: string + * format: date-time + * description: ISO timestamp of creation + * updated_at: + * type: string + * format: date-time + * description: ISO timestamp of last update + * required: + * - id + * - type + * - created_at + * - updated_at * CreateAgentRequest: + * allOf: + * - $ref: '#/components/schemas/AgentBase' + * - type: object + * properties: + * type: + * $ref: '#/components/schemas/AgentType' + * name: + * type: string + * minLength: 1 + * description: Agent name (required) + * model: + * type: string + * minLength: 1 + * description: Main model ID (required) + * required: + * - type + * - name + * - model + * + * UpdateAgentRequest: * type: object * properties: * name: @@ -100,9 +138,11 @@ const agentsRouter = express.Router() * description: * type: string * description: Agent description - * avatar: - * type: string - * description: Agent avatar URL + * accessible_paths: + * type: array + * items: + * type: string + * description: Array of directory paths the agent can access * instructions: * type: string * description: System prompt/instructions @@ -115,53 +155,409 @@ const agentsRouter = express.Router() * small_model: * type: string * description: Optional small/fast model ID - * built_in_tools: - * type: array - * items: - * type: string - * description: Built-in tool IDs * mcps: * type: array * items: * type: string - * description: MCP tool IDs - * knowledges: + * description: Array of MCP tool IDs + * allowed_tools: * type: array * items: * type: string - * description: Knowledge base IDs + * description: Array of allowed tool IDs (whitelist) * configuration: - * type: object - * description: Extensible settings + * $ref: '#/components/schemas/AgentConfiguration' + * description: Partial update - all fields are optional + * + * ReplaceAgentRequest: + * $ref: '#/components/schemas/AgentBase' + * + * SessionEntity: + * allOf: + * - $ref: '#/components/schemas/AgentBase' + * - type: object + * properties: + * id: + * type: string + * description: Unique session identifier + * agent_id: + * type: string + * description: Primary agent ID for the session + * agent_type: + * $ref: '#/components/schemas/AgentType' + * created_at: + * type: string + * format: date-time + * description: ISO timestamp of creation + * updated_at: + * type: string + * format: date-time + * description: ISO timestamp of last update + * required: + * - id + * - agent_id + * - agent_type + * - created_at + * - updated_at + * + * CreateSessionRequest: + * allOf: + * - $ref: '#/components/schemas/AgentBase' + * - type: object + * properties: + * model: + * type: string + * minLength: 1 + * description: Main model ID (required) + * required: + * - model + * + * UpdateSessionRequest: + * type: object + * properties: + * name: + * type: string + * description: Session name + * description: + * type: string + * description: Session description * accessible_paths: * type: array * items: * type: string - * description: Accessible directory paths - * permission_mode: + * description: Array of directory paths the agent can access + * instructions: * type: string - * enum: [readOnly, acceptEdits, bypassPermissions] - * description: Permission mode - * max_steps: - * type: integer - * description: Maximum steps the agent can take + * description: System prompt/instructions + * model: + * type: string + * description: Main model ID + * plan_model: + * type: string + * description: Optional planning model ID + * small_model: + * type: string + * description: Optional small/fast model ID + * mcps: + * type: array + * items: + * type: string + * description: Array of MCP tool IDs + * allowed_tools: + * type: array + * items: + * type: string + * description: Array of allowed tool IDs (whitelist) + * configuration: + * $ref: '#/components/schemas/AgentConfiguration' + * description: Partial update - all fields are optional + * + * ReplaceSessionRequest: + * allOf: + * - $ref: '#/components/schemas/AgentBase' + * - type: object + * properties: + * model: + * type: string + * minLength: 1 + * description: Main model ID (required) + * required: + * - model + * + * CreateSessionMessageRequest: + * type: object + * properties: + * content: + * type: string + * minLength: 1 + * description: Message content * required: - * - name - * - model + * - content + * + * PaginationQuery: + * type: object + * properties: + * limit: + * type: integer + * minimum: 1 + * maximum: 100 + * default: 20 + * description: Number of items to return + * offset: + * type: integer + * minimum: 0 + * default: 0 + * description: Number of items to skip + * status: + * type: string + * enum: [idle, running, completed, failed, stopped] + * description: Filter by session status + * + * ListAgentsResponse: + * type: object + * properties: + * agents: + * type: array + * items: + * $ref: '#/components/schemas/AgentEntity' + * total: + * type: integer + * description: Total number of agents + * limit: + * type: integer + * description: Number of items returned + * offset: + * type: integer + * description: Number of items skipped + * required: + * - agents + * - total + * - limit + * - offset + * + * ListSessionsResponse: + * type: object + * properties: + * sessions: + * type: array + * items: + * $ref: '#/components/schemas/SessionEntity' + * total: + * type: integer + * description: Total number of sessions + * limit: + * type: integer + * description: Number of items returned + * offset: + * type: integer + * description: Number of items skipped + * required: + * - sessions + * - total + * - limit + * - offset + * + * ErrorResponse: + * type: object + * properties: + * error: + * type: object + * properties: + * message: + * type: string + * description: Error message + * type: + * type: string + * description: Error type + * code: + * type: string + * description: Error code + * required: + * - message + * - type + * - code + * required: + * - error */ +/** + * @swagger + * /api/agents: + * post: + * summary: Create a new agent + * tags: [Agents] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/CreateAgentRequest' + * responses: + * 201: + * description: Agent created successfully + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/AgentEntity' + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ // Agent CRUD routes agentsRouter.post('/', validateAgent, handleValidationErrors, agentHandlers.createAgent) + +/** + * @swagger + * /api/agents: + * get: + * summary: List all agents with pagination + * tags: [Agents] + * parameters: + * - in: query + * name: limit + * schema: + * type: integer + * minimum: 1 + * maximum: 100 + * default: 20 + * description: Number of agents to return + * - in: query + * name: offset + * schema: + * type: integer + * minimum: 0 + * default: 0 + * description: Number of agents to skip + * - in: query + * name: status + * schema: + * type: string + * enum: [idle, running, completed, failed, stopped] + * description: Filter by agent status + * responses: + * 200: + * description: List of agents + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ListAgentsResponse' + */ agentsRouter.get('/', validatePagination, handleValidationErrors, agentHandlers.listAgents) + +/** + * @swagger + * /api/agents/{agentId}: + * get: + * summary: Get agent by ID + * tags: [Agents] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * responses: + * 200: + * description: Agent details + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/AgentEntity' + * 404: + * description: Agent not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ agentsRouter.get('/:agentId', validateAgentId, handleValidationErrors, agentHandlers.getAgent) -agentsRouter.put( - '/:agentId', - validateAgentId, - validateAgentReplace, - handleValidationErrors, - agentHandlers.updateAgent -) +/** + * @swagger + * /api/agents/{agentId}: + * put: + * summary: Replace agent (full update) + * tags: [Agents] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ReplaceAgentRequest' + * responses: + * 200: + * description: Agent updated successfully + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/AgentEntity' + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 404: + * description: Agent not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ +agentsRouter.put('/:agentId', validateAgentId, validateAgentReplace, handleValidationErrors, agentHandlers.updateAgent) +/** + * @swagger + * /api/agents/{agentId}: + * patch: + * summary: Update agent (partial update) + * tags: [Agents] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/UpdateAgentRequest' + * responses: + * 200: + * description: Agent updated successfully + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/AgentEntity' + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 404: + * description: Agent not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ agentsRouter.patch('/:agentId', validateAgentId, validateAgentUpdate, handleValidationErrors, agentHandlers.patchAgent) +/** + * @swagger + * /api/agents/{agentId}: + * delete: + * summary: Delete agent + * tags: [Agents] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * responses: + * 204: + * description: Agent deleted successfully + * 404: + * description: Agent not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ agentsRouter.delete('/:agentId', validateAgentId, handleValidationErrors, agentHandlers.deleteAgent) // Create sessions router with agent context @@ -169,9 +565,175 @@ const createSessionsRouter = (): express.Router => { const sessionsRouter = express.Router({ mergeParams: true }) // Session CRUD routes (nested under agent) + /** + * @swagger + * /api/agents/{agentId}/sessions: + * post: + * summary: Create a new session for an agent + * tags: [Sessions] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/CreateSessionRequest' + * responses: + * 201: + * description: Session created successfully + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/SessionEntity' + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 404: + * description: Agent not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ sessionsRouter.post('/', validateSession, handleValidationErrors, sessionHandlers.createSession) + + /** + * @swagger + * /api/agents/{agentId}/sessions: + * get: + * summary: List sessions for an agent + * tags: [Sessions] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * - in: query + * name: limit + * schema: + * type: integer + * minimum: 1 + * maximum: 100 + * default: 20 + * description: Number of sessions to return + * - in: query + * name: offset + * schema: + * type: integer + * minimum: 0 + * default: 0 + * description: Number of sessions to skip + * - in: query + * name: status + * schema: + * type: string + * enum: [idle, running, completed, failed, stopped] + * description: Filter by session status + * responses: + * 200: + * description: List of sessions + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ListSessionsResponse' + * 404: + * description: Agent not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ sessionsRouter.get('/', validatePagination, handleValidationErrors, sessionHandlers.listSessions) + /** + * @swagger + * /api/agents/{agentId}/sessions/{sessionId}: + * get: + * summary: Get session by ID + * tags: [Sessions] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * - in: path + * name: sessionId + * required: true + * schema: + * type: string + * description: Session ID + * responses: + * 200: + * description: Session details + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/SessionEntity' + * 404: + * description: Agent or session not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ sessionsRouter.get('/:sessionId', validateSessionId, handleValidationErrors, sessionHandlers.getSession) + /** + * @swagger + * /api/agents/{agentId}/sessions/{sessionId}: + * put: + * summary: Replace session (full update) + * tags: [Sessions] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * - in: path + * name: sessionId + * required: true + * schema: + * type: string + * description: Session ID + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ReplaceSessionRequest' + * responses: + * 200: + * description: Session updated successfully + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/SessionEntity' + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 404: + * description: Agent or session not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ sessionsRouter.put( '/:sessionId', validateSessionId, @@ -179,6 +741,51 @@ const createSessionsRouter = (): express.Router => { handleValidationErrors, sessionHandlers.updateSession ) + /** + * @swagger + * /api/agents/{agentId}/sessions/{sessionId}: + * patch: + * summary: Update session (partial update) + * tags: [Sessions] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * - in: path + * name: sessionId + * required: true + * schema: + * type: string + * description: Session ID + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/UpdateSessionRequest' + * responses: + * 200: + * description: Session updated successfully + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/SessionEntity' + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 404: + * description: Agent or session not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ sessionsRouter.patch( '/:sessionId', validateSessionId, @@ -186,6 +793,35 @@ const createSessionsRouter = (): express.Router => { handleValidationErrors, sessionHandlers.patchSession ) + /** + * @swagger + * /api/agents/{agentId}/sessions/{sessionId}: + * delete: + * summary: Delete session + * tags: [Sessions] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * - in: path + * name: sessionId + * required: true + * schema: + * type: string + * description: Session ID + * responses: + * 204: + * description: Session deleted successfully + * 404: + * description: Agent or session not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ sessionsRouter.delete('/:sessionId', validateSessionId, handleValidationErrors, sessionHandlers.deleteSession) return sessionsRouter @@ -196,6 +832,77 @@ const createMessagesRouter = (): express.Router => { const messagesRouter = express.Router({ mergeParams: true }) // Message CRUD routes (nested under agent/session) + /** + * @swagger + * /api/agents/{agentId}/sessions/{sessionId}/messages: + * post: + * summary: Create a new message in a session + * tags: [Messages] + * parameters: + * - in: path + * name: agentId + * required: true + * schema: + * type: string + * description: Agent ID + * - in: path + * name: sessionId + * required: true + * schema: + * type: string + * description: Session ID + * requestBody: + * required: true + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/CreateSessionMessageRequest' + * responses: + * 201: + * description: Message created successfully + * content: + * application/json: + * schema: + * type: object + * properties: + * id: + * type: number + * description: Message ID + * session_id: + * type: string + * description: Session ID + * role: + * type: string + * enum: [assistant, user, system, tool] + * description: Message role + * content: + * type: object + * description: Message content (AI SDK format) + * agent_session_id: + * type: string + * description: Agent session ID for resuming + * metadata: + * type: object + * description: Additional metadata + * created_at: + * type: string + * format: date-time + * updated_at: + * type: string + * format: date-time + * 400: + * description: Invalid request body + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 404: + * description: Agent or session not found + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ messagesRouter.post('/', validateSessionMessage, handleValidationErrors, messageHandlers.createMessage) return messagesRouter }