This commit is contained in:
161
docs/specs/agent-backend-gaps.md
Normal file
161
docs/specs/agent-backend-gaps.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Agent System — Backend Gaps Spec
|
||||
|
||||
## Status: ✅ Complete (all endpoints implemented 2026-03-26)
|
||||
## Date: 2026-03-26
|
||||
|
||||
---
|
||||
|
||||
## 1. Summary
|
||||
|
||||
The Agents frontend (`AgentsApp.tsx`) and adapter (`adapter.ts`) call several backend endpoints that either don't exist or have mismatched semantics. This spec documents every gap and proposes the backend work needed.
|
||||
|
||||
---
|
||||
|
||||
## 2. Frontend ↔ Backend Route Mapping
|
||||
|
||||
### 2.1 Personas (Agents) — `/api/personas`
|
||||
|
||||
The frontend uses "Personas" as its API namespace for individual agents. The local server (`packages/server/src/local/routes/personas.ts`) implements:
|
||||
|
||||
| Frontend call | Backend route | Status |
|
||||
|---|---|---|
|
||||
| `GET /api/personas` | ✅ Exists (local) | Works — returns persona catalog |
|
||||
| `POST /api/personas` | ✅ Exists (local) | Works — creates custom persona on disk |
|
||||
| `DELETE /api/personas/:id` | ✅ Exists (local) | Works — deletes custom persona |
|
||||
| `PATCH /api/personas/:id` | ❌ **MISSING** | Frontend calls PATCH to update custom personas |
|
||||
| `POST /api/personas/generate` | ❌ **MISSING** | Frontend calls this for AI-generated persona creation |
|
||||
|
||||
**Note:** The team server (`packages/server/src/routes/agents.ts`) has a separate `agents` CRUD backed by Postgres. These are different entities from local personas. The frontend conflates them — it calls `/api/personas` for both local and team use. This needs reconciliation.
|
||||
|
||||
### 2.2 Agent Groups — `/api/agent-groups`
|
||||
|
||||
| Frontend call | Backend route | Status |
|
||||
|---|---|---|
|
||||
| `GET /api/agent-groups` | ✅ Exists (team server) | Works |
|
||||
| `POST /api/agent-groups` | ✅ Exists (team server) | Works |
|
||||
| `GET /api/agent-groups/:id` | ✅ Exists (team server) | Works |
|
||||
| `POST /api/agent-groups/:id/run` | ✅ Exists (team server) | Works — queues job |
|
||||
| `PATCH /api/agent-groups/:id` | ❌ **MISSING** | Frontend calls this to update group name/strategy/members |
|
||||
| `DELETE /api/agent-groups/:id` | ❌ **MISSING** | Frontend calls this to delete a group |
|
||||
|
||||
### 2.3 Jobs — `/api/jobs`
|
||||
|
||||
| Frontend call | Backend route | Status |
|
||||
|---|---|---|
|
||||
| `GET /api/jobs/:id` | ✅ Exists (team server) | Works |
|
||||
| `POST /api/jobs/:id/cancel` | ❌ **MISSING** | Frontend calls this to cancel running group execution |
|
||||
|
||||
---
|
||||
|
||||
## 3. Required Backend Work
|
||||
|
||||
### 3.1 `PATCH /api/personas/:id` (Local Server)
|
||||
|
||||
Update a custom persona's fields (name, description, icon, systemPrompt, tools).
|
||||
|
||||
```
|
||||
PATCH /api/personas/:id
|
||||
Body: { name?, description?, icon?, systemPrompt?, tools? }
|
||||
Response: Updated persona object
|
||||
```
|
||||
|
||||
Implementation: Read existing persona JSON from disk, merge fields, write back via `saveCustomPersona()`.
|
||||
|
||||
### 3.2 `POST /api/personas/generate` (Local Server)
|
||||
|
||||
AI-generate a persona definition from a natural language prompt.
|
||||
|
||||
```
|
||||
POST /api/personas/generate
|
||||
Body: { prompt: string }
|
||||
Response: { name, description, systemPrompt, tools: string[] }
|
||||
```
|
||||
|
||||
Implementation: Call LiteLLM with a meta-prompt that produces persona JSON. Do NOT save — just return the generated config for the user to review/edit before saving.
|
||||
|
||||
### 3.3 `PATCH /api/agent-groups/:id` (Team Server)
|
||||
|
||||
Update an agent group's name, description, strategy, and/or member list.
|
||||
|
||||
```
|
||||
PATCH /api/agent-groups/:id
|
||||
Body: { name?, description?, strategy?, members?: Array<{ agentId, roleInGroup, executionOrder }> }
|
||||
Response: Updated group with members
|
||||
```
|
||||
|
||||
Implementation:
|
||||
1. Verify ownership (userId match)
|
||||
2. Update `agent_groups` row
|
||||
3. If `members` provided: DELETE existing `agent_group_members` for this group, INSERT new set
|
||||
4. Return group + members
|
||||
|
||||
### 3.4 `DELETE /api/agent-groups/:id` (Team Server)
|
||||
|
||||
```
|
||||
DELETE /api/agent-groups/:id
|
||||
Response: 204 No Content
|
||||
```
|
||||
|
||||
Implementation:
|
||||
1. Verify ownership
|
||||
2. DELETE `agent_group_members` WHERE groupId = :id
|
||||
3. DELETE `agent_groups` WHERE id = :id
|
||||
|
||||
### 3.5 `POST /api/jobs/:id/cancel` (Team Server)
|
||||
|
||||
Cancel a running or queued job.
|
||||
|
||||
```
|
||||
POST /api/jobs/:id/cancel
|
||||
Response: { cancelled: true, jobId: string }
|
||||
```
|
||||
|
||||
Implementation:
|
||||
1. Look up job in `agent_jobs`
|
||||
2. If status is `queued` or `running`: update status to `cancelled`, set `completedAt`
|
||||
3. If BullMQ job exists: call `job.remove()` or `job.moveToFailed()`
|
||||
4. Return success
|
||||
|
||||
### 3.6 Workspace ↔ Agent Group Assignment
|
||||
|
||||
Currently workspaces can have a `persona` (single agent). They should also support an `agentGroupId` so a group of agents can be assigned to handle workspace tasks collaboratively.
|
||||
|
||||
**Local workspace manager:** Add optional `agentGroupId` field to workspace config.
|
||||
**Team server:** Add `agent_group_id` column to relevant workspace/session table if using Postgres workspaces.
|
||||
**PATCH /api/workspaces/:id:** Accept `agentGroupId` field.
|
||||
**Chat routing:** When a workspace has `agentGroupId` set, the chat handler should dispatch to the group execution pipeline instead of single-agent loop.
|
||||
|
||||
---
|
||||
|
||||
## 4. Frontend ↔ Backend Reconciliation: Personas vs Agents
|
||||
|
||||
The local server uses file-based "personas" (`~/.waggle/personas/`) while the team server uses Postgres-backed "agents" (`agents` table). The frontend adapter calls `/api/personas` for both.
|
||||
|
||||
**Recommendation:** The local server should proxy or merge both sources:
|
||||
- Built-in + custom personas from disk (local)
|
||||
- Team agents from Postgres (team server, if connected)
|
||||
|
||||
This way the frontend has a single `/api/personas` endpoint that returns a unified list.
|
||||
|
||||
---
|
||||
|
||||
## 5. Data Flow: Group on Workspace
|
||||
|
||||
```
|
||||
User selects group in CreateWorkspaceDialog or PersonaSwitcher
|
||||
→ PATCH /api/workspaces/:id { agentGroupId: "..." }
|
||||
→ Chat sends message to workspace
|
||||
→ Backend detects agentGroupId on workspace config
|
||||
→ Routes to group execution pipeline (parallel/sequential/coordinator)
|
||||
→ SSE events stream per-member progress back to UI
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Priority Order
|
||||
|
||||
1. **PATCH/DELETE agent-groups** — Needed for existing UI (edit/delete groups)
|
||||
2. **PATCH personas** — Needed for editing custom agents
|
||||
3. **POST personas/generate** — Needed for AI agent creation
|
||||
4. **POST jobs/:id/cancel** — Needed for cancelling group runs
|
||||
5. **Workspace agentGroupId** — New feature (group assignment to workspaces)
|
||||
Reference in New Issue
Block a user