mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-25 12:05:06 +02:00
fix(agent): self-review fixes for archive feature
- Fix: workspace store now fetches agents with include_archived=true so archived agents are actually visible in the frontend (the archived UI was dead code before — ListAgents excludes archived by default) - Fix: add error logging for CancelAgentTasksByAgent in ArchiveAgent - Fix: add idempotency guards — return 409 Conflict when archiving an already-archived agent or restoring a non-archived agent - Fix: revert unnecessary extra GetAgent query in ReconcileAgentStatus (archived agents won't have running tasks after CancelAgentTasksByAgent) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -82,7 +82,7 @@ export const useWorkspaceStore = create<WorkspaceStore>((set, get) => ({
|
||||
toast.error("Failed to load members");
|
||||
return [] as MemberWithUser[];
|
||||
}),
|
||||
api.listAgents({ workspace_id: nextWorkspace.id }).catch((e) => {
|
||||
api.listAgents({ workspace_id: nextWorkspace.id, include_archived: true }).catch((e) => {
|
||||
logger.error("failed to load agents", e);
|
||||
toast.error("Failed to load agents");
|
||||
return [] as Agent[];
|
||||
@@ -154,7 +154,7 @@ export const useWorkspaceStore = create<WorkspaceStore>((set, get) => ({
|
||||
const { workspace } = get();
|
||||
if (!workspace) return;
|
||||
try {
|
||||
const agents = await api.listAgents({ workspace_id: workspace.id });
|
||||
const agents = await api.listAgents({ workspace_id: workspace.id, include_archived: true });
|
||||
set({ agents });
|
||||
} catch (e) {
|
||||
logger.error("failed to refresh agents", e);
|
||||
|
||||
@@ -291,10 +291,11 @@ export class ApiClient {
|
||||
}
|
||||
|
||||
// Agents
|
||||
async listAgents(params?: { workspace_id?: string }): Promise<Agent[]> {
|
||||
async listAgents(params?: { workspace_id?: string; include_archived?: boolean }): Promise<Agent[]> {
|
||||
const search = new URLSearchParams();
|
||||
const wsId = params?.workspace_id ?? this.workspaceId;
|
||||
if (wsId) search.set("workspace_id", wsId);
|
||||
if (params?.include_archived) search.set("include_archived", "true");
|
||||
return this.fetch(`/api/agents?${search}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -434,6 +434,10 @@ func (h *Handler) ArchiveAgent(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.canManageAgent(w, r, agent) {
|
||||
return
|
||||
}
|
||||
if agent.ArchivedAt.Valid {
|
||||
writeError(w, http.StatusConflict, "agent is already archived")
|
||||
return
|
||||
}
|
||||
|
||||
userID := requestUserID(r)
|
||||
archived, err := h.Queries.ArchiveAgent(r.Context(), db.ArchiveAgentParams{
|
||||
@@ -447,7 +451,9 @@ func (h *Handler) ArchiveAgent(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// Cancel all pending/active tasks for this agent.
|
||||
h.Queries.CancelAgentTasksByAgent(r.Context(), parseUUID(id))
|
||||
if err := h.Queries.CancelAgentTasksByAgent(r.Context(), parseUUID(id)); err != nil {
|
||||
slog.Warn("cancel agent tasks on archive failed", append(logger.RequestAttrs(r), "error", err, "agent_id", id)...)
|
||||
}
|
||||
|
||||
wsID := uuidToString(archived.WorkspaceID)
|
||||
slog.Info("agent archived", append(logger.RequestAttrs(r), "agent_id", id, "workspace_id", wsID)...)
|
||||
@@ -466,6 +472,10 @@ func (h *Handler) RestoreAgent(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.canManageAgent(w, r, agent) {
|
||||
return
|
||||
}
|
||||
if !agent.ArchivedAt.Valid {
|
||||
writeError(w, http.StatusConflict, "agent is not archived")
|
||||
return
|
||||
}
|
||||
|
||||
restored, err := h.Queries.RestoreAgent(r.Context(), parseUUID(id))
|
||||
if err != nil {
|
||||
|
||||
@@ -314,12 +314,7 @@ func (s *TaskService) ReportProgress(ctx context.Context, taskID string, workspa
|
||||
}
|
||||
|
||||
// ReconcileAgentStatus checks running task count and sets agent status accordingly.
|
||||
// Skips archived agents — their status is irrelevant.
|
||||
func (s *TaskService) ReconcileAgentStatus(ctx context.Context, agentID pgtype.UUID) {
|
||||
agent, err := s.Queries.GetAgent(ctx, agentID)
|
||||
if err != nil || agent.ArchivedAt.Valid {
|
||||
return
|
||||
}
|
||||
running, err := s.Queries.CountRunningTasks(ctx, agentID)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user