From 5cb2e3d51b30b94e5601923c36459e7c30ec4222 Mon Sep 17 00:00:00 2001 From: Kosta Petan Date: Tue, 20 Feb 2024 18:51:28 +0000 Subject: [PATCH] streams WIP --- .../Services/GithubWebHookProcessor.cs | 51 +++++++++++-------- .../Actors/DevLead/DeveloperLead.cs | 2 +- .../Actors/Developer/Developer.cs | 2 +- .../Actors/ProductManager/ProductManager.cs | 2 +- src/libs/Microsoft.AI.DevTeam/Events/Event.cs | 6 +-- .../Services/GithubService.cs | 2 +- 6 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/apps/gh-flow/Services/GithubWebHookProcessor.cs b/src/apps/gh-flow/Services/GithubWebHookProcessor.cs index 606b4fcec..e28e85140 100644 --- a/src/apps/gh-flow/Services/GithubWebHookProcessor.cs +++ b/src/apps/gh-flow/Services/GithubWebHookProcessor.cs @@ -37,7 +37,8 @@ public sealed class GithubWebHookProcessor : WebhookEventProcessor .Select(l => l.Name.Split('.')) .Where(parts => parts.Length == 2) .ToDictionary(parts => parts[0], parts => parts[1]); - //if(labels.ContainsKey("Parent")) + var skillName = labels.Keys.Where(k=>k != "Parent").FirstOrDefault(); + long? parentNumber = labels.ContainsKey("Parent") ? long.Parse(labels["Parent"]) : null; // TODO: confert the non-parent label to skill and function // Issue 1 // Sub issue 2 @@ -74,12 +75,12 @@ public sealed class GithubWebHookProcessor : WebhookEventProcessor if (issuesEvent.Action == IssuesAction.Opened) { _logger.LogInformation("Processing HandleNewAsk"); - await HandleNewAsk(issueNumber, skillName, functionName, suffix, input, org, repo); + await HandleNewAsk(issueNumber,parentNumber, skillName, labels[skillName], suffix, input, org, repo); } else if (issuesEvent.Action == IssuesAction.Closed && issuesEvent.Issue.User.Type.Value == UserType.Bot) { _logger.LogInformation("Processing HandleClosingIssue"); - await HandleClosingIssue(issueNumber, skillName, functionName, suffix, org, repo); + await HandleClosingIssue(issueNumber, parentNumber, suffix, org, repo); } } catch (System.Exception) @@ -101,15 +102,17 @@ public sealed class GithubWebHookProcessor : WebhookEventProcessor var issueNumber = issueCommentEvent.Issue.Number; var input = issueCommentEvent.Issue.Body; // Assumes the label follows the following convention: Skill.Function example: PM.Readme - var labels = issueCommentEvent.Issue.Labels.First().Name.Split("."); - - var skillName = labels[0]; - var functionName = labels[1]; + var labels = issueCommentEvent.Issue.Labels + .Select(l => l.Name.Split('.')) + .Where(parts => parts.Length == 2) + .ToDictionary(parts => parts[0], parts => parts[1]); + var skillName = labels.Keys.Where(k=>k != "Parent").FirstOrDefault(); + long? parentNumber = labels.ContainsKey("Parent") ? long.Parse(labels["Parent"]) : null; var suffix = $"{org}-{repo}"; // we only resond to non-bot comments if (issueCommentEvent.Sender.Type.Value != UserType.Bot) { - await HandleNewAsk(issueNumber, skillName, functionName, suffix, input, org, repo); + await HandleNewAsk(issueNumber, parentNumber, skillName, labels[skillName], suffix, input, org, repo); } } catch (System.Exception ex) @@ -119,22 +122,27 @@ public sealed class GithubWebHookProcessor : WebhookEventProcessor } - private async Task HandleClosingIssue(long issueNumber, string skillName, string functionName, string suffix, string org, string repo) + private async Task HandleClosingIssue(long issueNumber, long? parentNumber, string suffix, string org, string repo) { var streamProvider = _client.GetStreamProvider("StreamProvider"); var streamId = StreamId.Create(suffix, issueNumber.ToString()); var stream = streamProvider.GetStream(streamId); + var data = new Dictionary + { + { "org", org }, + { "repo", repo }, + { "issueNumber", issueNumber.ToString() }, + { "parentNumber", parentNumber?.ToString()} + }; await stream.OnNextAsync(new Event { Type = EventType.ChainClosed, - Org = org, - Repo = repo, - IssueNumber = issueNumber + Data = data }); } - private async Task HandleNewAsk(long issueNumber, string skillName, string functionName, string suffix, string input, string org, string repo) + private async Task HandleNewAsk(long issueNumber, long? parentNumber, string skillName, string functionName, string suffix, string input, string org, string repo) { try { @@ -150,21 +158,20 @@ public sealed class GithubWebHookProcessor : WebhookEventProcessor (nameof(DevLead), nameof(DevLead.Plan)) => EventType.NewAskPlan, (nameof(Developer), nameof(Developer.Implement)) => EventType.NewAskImplement, _ => EventType.NewAsk + }; + var data = new Dictionary + { + { "org", org }, + { "repo", repo }, + { "issueNumber", issueNumber.ToString() }, + { "parentNumber", parentNumber?.ToString()} }; await stream.OnNextAsync(new Event { Type = eventType, Message = input, - Org = org, - Repo = repo, - IssueNumber = issueNumber + Data = data }); - - // else if (skillName == "Repo" && functionName == "Ingest") - // { - // var ingestor = _grains.GetGrain(suffix); - // await ingestor.IngestionFlow(org, repo, "main"); - // } } catch (System.Exception) { diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs b/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs index 0a49b4881..434cf3752 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/DevLead/DeveloperLead.cs @@ -115,7 +115,7 @@ public class DeveloperLead : SemanticPersona switch (item.Type) { case EventType.NewAsk: - await CreateIssue(item.Org, item.Repo, item.IssueNumber, item.Message); + await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]) , item.Message); break; case EventType.NewAskPlan: await CreatePlan(item.Message); diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs b/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs index 746c3cc0b..8f8681780 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/Developer/Developer.cs @@ -80,7 +80,7 @@ public class Dev : SemanticPersona switch (item.Type) { case EventType.NewAsk: - await CreateIssue(item.Org, item.Repo, item.IssueNumber, item.Message); + await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]) , item.Message); break; case EventType.NewAskImplement: await GenerateCode(item.Message); diff --git a/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs b/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs index 6073e6828..22a7a84c9 100644 --- a/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs +++ b/src/libs/Microsoft.AI.DevTeam/Actors/ProductManager/ProductManager.cs @@ -42,7 +42,7 @@ public class ProductManager : SemanticPersona switch (item.Type) { case EventType.NewAsk: - await CreateIssue(item.Org, item.Repo, item.IssueNumber, item.Message); + await CreateIssue(item.Data["org"], item.Data["repo"], long.Parse(item.Data["issueNumber"]) , item.Message); break; case EventType.NewAskReadme: await CreateReadme(item.Message); diff --git a/src/libs/Microsoft.AI.DevTeam/Events/Event.cs b/src/libs/Microsoft.AI.DevTeam/Events/Event.cs index 1dd3aaf8c..d1c7c0f82 100644 --- a/src/libs/Microsoft.AI.DevTeam/Events/Event.cs +++ b/src/libs/Microsoft.AI.DevTeam/Events/Event.cs @@ -7,11 +7,7 @@ public class Event [Id(1)] public string Message { get; set; } [Id(2)] - public string Org { get; set; } - [Id(3)] - public string Repo { get; set; } - [Id(4)] - public long IssueNumber { get; set; } + public Dictionary Data { get; set; } } public enum EventType diff --git a/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs b/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs index 3fd7d1e6a..bdcdc7f2e 100644 --- a/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs +++ b/src/libs/Microsoft.AI.DevTeam/Services/GithubService.cs @@ -110,9 +110,9 @@ public class GithubService : IManageGithub var newIssue = new NewIssue($"{request.Label} chain for #{request.ParentNumber}") { Body = request.Input, - }; newIssue.Labels.Add(request.Label); + newIssue.Labels.Add($"Parent.{request.ParentNumber}"); var issue = await _ghClient.Issue.Create(request.Org, request.Repo, newIssue); var commentBody = $" - [ ] #{issue.Number} - tracks {request.Label}"; var comment = await _ghClient.Issue.Comment.Create(request.Org, request.Repo, (int)request.ParentNumber, commentBody);