Files
kandev/apps/backend/internal/task/dto/task_activity.go
T
2026-07-26 14:18:35 +01:00

65 lines
2.1 KiB
Go

package dto
import (
"github.com/kandev/kandev/internal/task/models"
v1 "github.com/kandev/kandev/pkg/api/v1"
)
// EnrichTaskForegroundActivity stamps the task-level MOST-ACTIVE-WINS activity
// aggregate onto a TaskDTO from the task's sessions. It is a no-op for a nil DTO
// or nil provider. ForegroundActivity is omitted when no activity is known;
// ActiveSubagentCount is always serialized as zero when no provider or live
// subagent is available. The provider is consulted for RUNNING sessions and for
// settled sessions that may still carry detached background liveness.
func EnrichTaskForegroundActivity(dto *TaskDTO, sessions []*models.TaskSession, provider ForegroundActivityProvider) {
if dto == nil || provider == nil {
return
}
dto.ForegroundActivity = v1.AggregateForegroundActivity(sessionForegroundActivities(sessions, provider))
dto.ActiveSubagentCount = taskActiveSubagentCount(sessions, provider)
}
func taskActiveSubagentCount(
sessions []*models.TaskSession,
provider ForegroundActivityProvider,
) int {
countProvider, ok := provider.(ActiveSubagentCountProvider)
if !ok {
return 0
}
total := 0
for _, session := range sessions {
if session != nil {
total += countProvider.ActiveSubagentCount(session.ID)
}
}
return total
}
// sessionForegroundActivities resolves generating activity for RUNNING sessions
// and detached background activity for any coarse state.
func sessionForegroundActivities(sessions []*models.TaskSession, provider ForegroundActivityProvider) []v1.ForegroundActivity {
activities := make([]v1.ForegroundActivity, 0, len(sessions))
for _, session := range sessions {
if session == nil {
continue
}
if activity, ok := sessionForegroundActivity(session.ID, session.State, provider); ok {
activities = append(activities, activity)
}
}
return activities
}
func sessionForegroundActivity(
sessionID string,
state models.TaskSessionState,
provider ForegroundActivityProvider,
) (v1.ForegroundActivity, bool) {
activity := provider.ForegroundActivity(sessionID)
if state == models.TaskSessionStateRunning || activity == v1.ForegroundActivityBackground {
return activity, true
}
return "", false
}