@@ -11,6 +11,7 @@ import (
1111 "github.com/memodb-io/Acontext/internal/modules/model"
1212 "github.com/memodb-io/Acontext/internal/modules/repo"
1313 "github.com/memodb-io/Acontext/internal/pkg/paging"
14+ "go.uber.org/zap"
1415 "gorm.io/gorm"
1516)
1617
@@ -85,9 +86,11 @@ type learningSpaceService struct {
8586 lsSessRepo repo.LearningSpaceSessionRepo
8687 skillsRepo repo.AgentSkillsRepo
8788 sessionRepo repo.SessionRepo
89+ taskRepo repo.TaskRepo
8890 agentSkillsSvc AgentSkillsService
8991 artifactSvc ArtifactService
9092 templateFS fs.ReadFileFS
93+ logger * zap.Logger
9194}
9295
9396// DefaultSkillTemplatePaths lists the embedded template paths created alongside
@@ -104,19 +107,23 @@ func NewLearningSpaceService(
104107 lsSessRepo repo.LearningSpaceSessionRepo ,
105108 skillsRepo repo.AgentSkillsRepo ,
106109 sessionRepo repo.SessionRepo ,
110+ taskRepo repo.TaskRepo ,
107111 agentSkillsSvc AgentSkillsService ,
108112 artifactSvc ArtifactService ,
109113 templateFS fs.ReadFileFS ,
114+ logger * zap.Logger ,
110115) LearningSpaceService {
111116 return & learningSpaceService {
112117 lsRepo : lsRepo ,
113118 lsSkillRepo : lsSkillRepo ,
114119 lsSessRepo : lsSessRepo ,
115120 skillsRepo : skillsRepo ,
116121 sessionRepo : sessionRepo ,
122+ taskRepo : taskRepo ,
117123 agentSkillsSvc : agentSkillsSvc ,
118124 artifactSvc : artifactSvc ,
119125 templateFS : templateFS ,
126+ logger : logger ,
120127 }
121128}
122129
@@ -385,6 +392,7 @@ func (s *learningSpaceService) GetSession(ctx context.Context, projectID, learni
385392 }
386393 return nil , err
387394 }
395+ s .resolvePendingStatus (ctx , lss )
388396 return lss , nil
389397}
390398
@@ -394,7 +402,59 @@ func (s *learningSpaceService) ListSessions(ctx context.Context, projectID, lear
394402 return nil , err
395403 }
396404
397- return s .lsSessRepo .ListBySpaceID (ctx , learningSpaceID )
405+ sessions , err := s .lsSessRepo .ListBySpaceID (ctx , learningSpaceID )
406+ if err != nil {
407+ return nil , err
408+ }
409+ for _ , lss := range sessions {
410+ s .resolvePendingStatus (ctx , lss )
411+ }
412+ return sessions , nil
413+ }
414+
415+ // resolvePendingStatus lazily resolves a "pending" learning session to a
416+ // terminal status when it's clear that no SkillLearnTask will ever arrive.
417+ // The resolved status is persisted to the DB so subsequent reads skip the check.
418+ func (s * learningSpaceService ) resolvePendingStatus (ctx context.Context , lss * model.LearningSpaceSession ) {
419+ if lss .Status != "pending" {
420+ return
421+ }
422+
423+ hasUnfinished , err := s .sessionRepo .HasUnfinishedMessages (ctx , lss .SessionID )
424+ if err != nil {
425+ s .logger .Warn ("lazy status resolution: failed to check unfinished messages" ,
426+ zap .String ("session_id" , lss .SessionID .String ()), zap .Error (err ))
427+ return
428+ }
429+ if hasUnfinished {
430+ return
431+ }
432+
433+ hasSuccess , err := s .taskRepo .HasSuccessTask (ctx , lss .SessionID )
434+ if err != nil {
435+ s .logger .Warn ("lazy status resolution: failed to check success tasks" ,
436+ zap .String ("session_id" , lss .SessionID .String ()), zap .Error (err ))
437+ return
438+ }
439+ if hasSuccess {
440+ return
441+ }
442+
443+ resolvedStatus := "completed"
444+ hasFailed , err := s .sessionRepo .HasFailedMessages (ctx , lss .SessionID )
445+ if err != nil {
446+ s .logger .Warn ("lazy status resolution: failed to check failed messages, defaulting to completed" ,
447+ zap .String ("session_id" , lss .SessionID .String ()), zap .Error (err ))
448+ } else if hasFailed {
449+ resolvedStatus = "failed"
450+ }
451+
452+ if err := s .lsSessRepo .UpdateStatus (ctx , lss .LearningSpaceID , lss .SessionID , resolvedStatus ); err != nil {
453+ s .logger .Warn ("lazy status resolution: failed to persist resolved status" ,
454+ zap .String ("session_id" , lss .SessionID .String ()),
455+ zap .String ("resolved_status" , resolvedStatus ), zap .Error (err ))
456+ }
457+ lss .Status = resolvedStatus
398458}
399459
400460func (s * learningSpaceService ) ExcludeSkill (ctx context.Context , projectID , learningSpaceID , skillID uuid.UUID ) error {
0 commit comments