diff --git a/src/apps/gh-flow/Services/GithubWebHookProcessor.cs b/src/apps/gh-flow/Services/GithubWebHookProcessor.cs index e28e85140..0a56fad5f 100644 --- a/src/apps/gh-flow/Services/GithubWebHookProcessor.cs +++ b/src/apps/gh-flow/Services/GithubWebHookProcessor.cs @@ -64,13 +64,6 @@ public sealed class GithubWebHookProcessor : WebhookEventProcessor // org+repo+3 // PM - - // Connect the parent issue with child via label - - // Parent:3 - // Parent:4 - - var suffix = $"{org}-{repo}"; if (issuesEvent.Action == IssuesAction.Opened) { diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs b/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs index 434cf3752..4079eeecf 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs @@ -48,6 +48,7 @@ public class DeveloperLead : SemanticPersona }); _state.State.ParentIssueNumber = parentNumber; + _state.State.CommentId = devLeadIssue.CommentId; await _state.WriteStateAsync(); } public async Task CreatePlan(string ask) @@ -86,21 +87,34 @@ public class DeveloperLead : SemanticPersona } } - public async Task ClosePlan() + public async Task ClosePlan(string org, string repo, long issueNumber, long parentNumber) { - // var devLead = _grains.GetGrain(issueNumber, suffix); - // var lookup = _grains.GetGrain(suffix); - // var parentIssue = await lookup.GetMetadata((int)issueNumber); - // var conductor = _grains.GetGrain(parentIssue.IssueNumber, suffix); - // var plan = await devLead.GetLatestPlan(); - // await conductor.ImplementationFlow(plan, org, repo, parentIssue.IssueNumber); + var plan = await GetLatestPlan(); + var suffix = $"{org}-{repo}"; + var streamProvider = this.GetStreamProvider("StreamProvider"); + var streamId = StreamId.Create("developers", suffix+parentNumber.ToString()); + var stream = streamProvider.GetStream(streamId); - // await _ghService.MarkTaskComplete(new MarkTaskCompleteRequest - // { - // Org = org, - // Repo = repo, - // CommentId = parentIssue.CommentId - // }); + var eventTasks = plan.steps.SelectMany(s => s.subtasks.Select(st => stream.OnNextAsync(new Event { + Type = EventType.NewAsk, + Data = new Dictionary + { + { "org", org }, + { "repo", repo }, + { "parentNumber", parentNumber.ToString()} + }, + Message = st.prompt + }))); + + Task.WaitAll(eventTasks.ToArray()); + //await conductor.ImplementationFlow(plan, org, repo, parentIssue.IssueNumber); + + await _ghService.MarkTaskComplete(new MarkTaskCompleteRequest + { + Org = org, + Repo = repo, + CommentId = _state.State.CommentId + }); } public Task GetLatestPlan() @@ -118,10 +132,11 @@ public class DeveloperLead : SemanticPersona await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]) , item.Message); break; case EventType.NewAskPlan: - await CreatePlan(item.Message); + var plan = await CreatePlan(item.Message); + await _ghService.PostComment(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]), plan); break; case EventType.ChainClosed: - await ClosePlan(); + await ClosePlan(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]), long.Parse(item.Data["parentNumber"])); break; default: break; diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs b/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs index 8f8681780..4053637ce 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs @@ -9,6 +9,8 @@ using Orleans.Streams; namespace Microsoft.AI.DevTeam; +//[RegexImplicitStreamSubscription("")] +[ImplicitStreamSubscription("developers")] public class Dev : SemanticPersona { private readonly IKernel _kernel; @@ -28,7 +30,7 @@ public class Dev : SemanticPersona public async Task CreateIssue(string org, string repo, long parentNumber, string input) { - var devLeadIssue = await _ghService.CreateIssue(new CreateIssueRequest + var devIssue = await _ghService.CreateIssue(new CreateIssueRequest { Label = $"{nameof(Developer)}.{nameof(Developer.Implement)}", Org = org, @@ -38,6 +40,7 @@ public class Dev : SemanticPersona }); _state.State.ParentIssueNumber = parentNumber; + _state.State.CommentId = devIssue.CommentId; await _state.WriteStateAsync(); } public async Task GenerateCode(string ask) @@ -80,10 +83,11 @@ public class Dev : SemanticPersona switch (item.Type) { case EventType.NewAsk: - await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]) , item.Message); + await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["parentNumber"]) , item.Message); break; case EventType.NewAskImplement: - await GenerateCode(item.Message); + var code = await GenerateCode(item.Message); + await _ghService.PostComment(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]), code); break; case EventType.ChainClosed: await CloseImplementation(); diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs b/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs index 22a7a84c9..8ebbb8dd6 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs @@ -45,7 +45,8 @@ public class ProductManager : SemanticPersona await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]) , item.Message); break; case EventType.NewAskReadme: - await CreateReadme(item.Message); + var readme = await CreateReadme(item.Message); + await _ghService.PostComment(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]), readme); break; case EventType.ChainClosed: await CloseReadme(); @@ -68,6 +69,7 @@ public class ProductManager : SemanticPersona }); _state.State.ParentIssueNumber = parentNumber; + _state.State.CommentId = pmIssue.CommentId; await _state.WriteStateAsync(); } diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/SemanticPersona.cs b/src/libs/Microsoft.AI.DevTeam/Actors/SemanticPersona.cs index c913c899b..6d0bd2a82 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/SemanticPersona.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/SemanticPersona.cs @@ -79,6 +79,7 @@ public class SemanticPersonaState public List History { get; set; } public string Understanding { get; set; } public long ParentIssueNumber { get; set; } + public int CommentId { get; set; } } public enum ChatUserType diff --git a/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs b/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs index bdcdc7f2e..c0af43cf0 100644 --- a/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs +++ b/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs @@ -158,17 +158,16 @@ public class GithubService : IManageGithub } - public async Task PostComment(PostCommentRequest request) + public async Task PostComment(string org, string repo, long issueNumber, string comment) { try { - await _ghClient.Issue.Comment.Create(request.Org, request.Repo, request.Number, request.Content); + await _ghClient.Issue.Comment.Create(org, repo, (int)issueNumber, comment); } catch (Exception ex) { _logger.LogError(ex, "Error posting comment"); } - } public async Task> GetFiles(string org, string repo, string branch, Func filter) @@ -232,7 +231,7 @@ public interface IManageGithub Task CreateBranch(CreateBranchRequest request); Task CommitToBranch(CommitRequest request); - Task PostComment(PostCommentRequest request); + Task PostComment(string org, string repo, long issueNumber, string comment); Task> GetFiles(string org, string repo, string branch, Func filter); Task GetMainLanguage(string org, string repo); }