fix(agent): update setAgentStatus to include tenantID parameter (#621)

Summoning failures (e.g. provider timeout) left agents stuck in summoning because failure paths called setAgentStatus(context.Background(), ...) without tenant scope, causing agent not found on update. Pass tenantID to setAgentStatus and re-attach tenant context when missing.
This commit is contained in:
Huy Doan authored and GitHub committed 2026-04-01 18:07:43 +07:00
1 parent 1b190fa0bb
commit 41c827c65f
2 files changed
+16 -8

No files matched your search

+4 -4
View File
@@ -104,7 +104,7 @@ func (s *AgentSummoner) SummonAgent(agentID uuid.UUID, tenantID uuid.UUID, provi
if !isRetryableError(err) {
slog.Warn("summoning: single-call failed (non-retryable)", "agent", agentID, "error", err)
s.emitEvent(agentID, tenantID, SummonEventFailed, "", err.Error())
s.setAgentStatus(context.Background(), agentID, store.AgentStatusSummonFailed)
s.setAgentStatus(context.Background(), tenantID, agentID, store.AgentStatusSummonFailed)
return
}
@@ -127,7 +127,7 @@ func (s *AgentSummoner) SummonAgent(agentID uuid.UUID, tenantID uuid.UUID, provi
if soulErr != nil {
slog.Warn("summoning: SOUL.md generation failed", "agent", agentID, "error", soulErr)
s.emitEvent(agentID, tenantID, SummonEventFailed, "", soulErr.Error())
s.setAgentStatus(context.Background(), agentID, store.AgentStatusSummonFailed)
s.setAgentStatus(context.Background(), tenantID, agentID, store.AgentStatusSummonFailed)
return
}
soulContent = soulFiles[bootstrap.SoulFile]
@@ -155,7 +155,7 @@ func (s *AgentSummoner) SummonAgent(agentID uuid.UUID, tenantID uuid.UUID, provi
if idErr != nil {
slog.Warn("summoning: IDENTITY.md generation failed", "agent", agentID, "error", idErr)
s.emitEvent(agentID, tenantID, SummonEventFailed, "", idErr.Error())
s.setAgentStatus(context.Background(), agentID, store.AgentStatusSummonFailed)
s.setAgentStatus(context.Background(), tenantID, agentID, store.AgentStatusSummonFailed)
return
}
identityContent = idFiles[bootstrap.IdentityFile]
@@ -198,7 +198,7 @@ func (s *AgentSummoner) finishSummon(ctx context.Context, agentID, tenantID uuid
slog.Warn("summoning: failed to save agent metadata", "agent", agentID, "error", err)
}
}
s.setAgentStatus(ctx, agentID, store.AgentStatusActive)
s.setAgentStatus(ctx, tenantID, agentID, store.AgentStatusActive)
s.emitEvent(agentID, tenantID, SummonEventCompleted, "", "")
slog.Info("summoning: completed", "agent", agentID)
}
+12 -4
View File
@@ -33,7 +33,7 @@ func (s *AgentSummoner) RegenerateAgent(agentID uuid.UUID, tenantID uuid.UUID, p
if err != nil {
slog.Warn("summoning: failed to read existing files", "agent", agentID, "error", err)
s.emitEvent(agentID, tenantID, SummonEventFailed, "", err.Error())
s.setAgentStatus(context.Background(), agentID, store.AgentStatusSummonFailed)
s.setAgentStatus(context.Background(), tenantID, agentID, store.AgentStatusSummonFailed)
return
}
@@ -44,7 +44,7 @@ func (s *AgentSummoner) RegenerateAgent(agentID uuid.UUID, tenantID uuid.UUID, p
slog.Warn("summoning: regeneration failed", "agent", agentID, "error", err)
s.emitEvent(agentID, tenantID, SummonEventFailed, "", err.Error())
// Use fresh context — the original may have timed out, but we still need to update status.
s.setAgentStatus(context.Background(), agentID, store.AgentStatusSummonFailed)
s.setAgentStatus(context.Background(), tenantID, agentID, store.AgentStatusSummonFailed)
return
}
@@ -64,7 +64,7 @@ func (s *AgentSummoner) RegenerateAgent(agentID uuid.UUID, tenantID uuid.UUID, p
}
}
s.setAgentStatus(ctx, agentID, store.AgentStatusActive)
s.setAgentStatus(ctx, tenantID, agentID, store.AgentStatusActive)
s.emitEvent(agentID, tenantID, SummonEventCompleted, "", "")
slog.Info("summoning: regeneration completed", "agent", agentID, "files", len(files))
@@ -191,7 +191,15 @@ func (s *AgentSummoner) ensureUserPredefined(ctx context.Context, agentID uuid.U
}
}
func (s *AgentSummoner) setAgentStatus(ctx context.Context, agentID uuid.UUID, status string) {
func (s *AgentSummoner) setAgentStatus(ctx context.Context, tenantID, agentID uuid.UUID, status string) {
// Summoning frequently calls this after a timeout/cancel path with context.Background().
// Re-attach tenant scope so AgentStore.Update targets the right tenant row.
if store.TenantIDFromContext(ctx) == uuid.Nil && !store.IsCrossTenant(ctx) {
if tenantID == uuid.Nil {
tenantID = store.MasterTenantID
}
ctx = store.WithTenantID(ctx, tenantID)
}
if err := s.agents.Update(ctx, agentID, map[string]any{"status": status}); err != nil {
slog.Warn("summoning: failed to update agent status", "agent", agentID, "status", status, "error", err)
}