public async Task SendAsync(KernelCommand kernelCommand, CancellationToken cancellationToken) { // FIX: remove this one as this is for backward compatibility await _sender.SendAsync("submitCommand", KernelCommandEnvelope.Serialize(KernelCommandEnvelope.Create(kernelCommand)), cancellationToken : cancellationToken); await _sender.SendAsync("kernelCommandFromServer", KernelCommandEnvelope.Serialize(KernelCommandEnvelope.Create(kernelCommand)), cancellationToken : cancellationToken); }
public async Task SendAsync(KernelCommand kernelCommand, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); _sender.WriteMessage(KernelCommandEnvelope.Serialize(KernelCommandEnvelope.Create(kernelCommand))); await _sender.FlushAsync(cancellationToken); }
public void Create_creates_envelope_with_reference_to_original_command() { IKernelCommand command = new SubmitCode("display(123)"); var envelope = KernelCommandEnvelope.Create(command); envelope.Command.Should().BeSameAs(command); }
public void Create_creates_envelope_of_the_correct_type() { IKernelCommand command = new SubmitCode("display(123)"); var envelope = KernelCommandEnvelope.Create(command); envelope.Should().BeOfType<KernelCommandEnvelope<SubmitCode>>(); }
public static Task WriteAsync( this StandardIOKernelServer server, KernelCommand command) { var json = KernelCommandEnvelope.Serialize( KernelCommandEnvelope.Create(command)); return(server.WriteAsync(json)); }
public async Task HandleAsync(SubmitCode command, KernelInvocationContext context) { var envelope = KernelCommandEnvelope.Create(command); _clientStream.WriteMessage(KernelCommandEnvelope.Serialize(envelope)); await _clientStream.FlushAsync(); await PollEvents(envelope.Token); }
public async Task when_a_KernelCommandEnvelope_is_received_it_reads_the_command() { var kernelCommand = new SubmitCode("x=1"); var message = KernelCommandEnvelope.Serialize(KernelCommandEnvelope.Create(kernelCommand)); using var stringReader = new StringReader(message); var receiver = new KernelCommandAndEventTextReceiver(stringReader); var d = await receiver.CommandsAndEventsAsync(CancellationToken.None).FirstAsync(); d.Command.Should().BeEquivalentTo(kernelCommand); }
public async Task when_a_KernelCommand_is_sent_it_writes_a_KernelCommandEnvelope() { var kernelCommand = new SubmitCode("x=1"); var buffer = new StringBuilder(); var sender = new KernelCommandAndEventTextStreamSender(new StringWriter(buffer)); await sender.SendAsync(kernelCommand, CancellationToken.None); var envelopeMessage = buffer.ToString(); envelopeMessage.Should() .BeEquivalentTo(KernelCommandEnvelope.Serialize(KernelCommandEnvelope.Create(kernelCommand)) + KernelCommandAndEventTextStreamSender.Delimiter); }
public async Task kernel_server_honors_log_path() { using var logPath = DisposableDirectory.Create(); using var outputReceived = new ManualResetEvent(false); var errorLines = new List <string>(); // start as external process var dotnet = new Dotnet(logPath.Directory); using var kernelServerProcess = dotnet.StartProcess( args: $@"""{typeof(Program).Assembly.Location}"" kernel-server --log-path ""{logPath.Directory.FullName}""", output: _line => { outputReceived.Set(); }, error: errorLines.Add); // wait for log file to be created var logFile = await logPath.Directory.WaitForFile( timeout : TimeSpan.FromSeconds(2), predicate : _file => true); // any matching file is the one we want errorLines.Should().BeEmpty(); logFile.Should().NotBeNull("unable to find created log file"); // submit code var submission = new SubmitCode("1+1"); var submissionJson = KernelCommandEnvelope.Serialize(KernelCommandEnvelope.Create(submission)); await kernelServerProcess.StandardInput.WriteLineAsync(submissionJson); await kernelServerProcess.StandardInput.FlushAsync(); // wait for output to proceed var gotOutput = outputReceived.WaitOne(timeout: TimeSpan.FromSeconds(2)); gotOutput.Should().BeTrue("expected to receive on stdout"); // kill kernelServerProcess.StandardInput.Close(); // simulate Ctrl+C await Task.Delay(TimeSpan.FromSeconds(2)); // allow logs to be flushed kernelServerProcess.Kill(); kernelServerProcess.WaitForExit(2000).Should().BeTrue(); errorLines.Should().BeEmpty(); // check log file for expected contents (await logFile.WaitForFileCondition( timeout: TimeSpan.FromSeconds(2), predicate: file => file.Length > 0)) .Should().BeTrue("expected non-empty log file"); var logFileContents = File.ReadAllText(logFile.FullName); logFileContents.Should().Contain("ℹ OnAssemblyLoad: "); }
public void All_command_types_are_round_trip_serializable(IKernelCommand command) { var originalEnvelope = KernelCommandEnvelope.Create(command); var json = KernelCommandEnvelope.Serialize(originalEnvelope); _output.WriteLine(json); var deserializedEnvelope = KernelCommandEnvelope.Deserialize(json); deserializedEnvelope .Should() .BeEquivalentTo(originalEnvelope); }
public void All_command_types_are_round_trip_serializable(KernelCommand command) { var originalEnvelope = KernelCommandEnvelope.Create(command); var json = KernelCommandEnvelope.Serialize(originalEnvelope); _output.WriteLine(json); var deserializedEnvelope = KernelCommandEnvelope.Deserialize(json); deserializedEnvelope .Should() .BeEquivalentTo(originalEnvelope, o => o.Excluding(e => e.Command.Properties) .Excluding(e => e.Command.Handler)); }
#pragma warning disable CS1998 protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken) { var value = turnContext.Activity; var attachments = turnContext.Activity.Attachments; if (turnContext.Activity.Value == null) // someone typed in something, it isn't a card { var content = turnContext.Activity.Text; var code = CheckForCode(content); var conversationReference = turnContext.Activity.GetConversationReference(); var mention = new Mention { Mentioned = turnContext.Activity.From, Text = $"<at>{turnContext.Activity.From.Name}</at>", }; if (!string.IsNullOrEmpty(code)) { if (DotNetInteractiveProcessRunner.Instance.CanExecuteCode) { var submissionToken = Guid.NewGuid().ToString("N"); var messageText = string.Empty; var user = UserGame.GetOrCreateUser(mention, turnContext.Activity.From); if (UserGame.CurrentChatUser?.Id != user.Id) { UserGame.CurrentChatUser = user; messageText = $"Hey {mention.Text} It looks like you're typing some code. Let me run it for you! 😊"; } else { messageText = UserGame.GetMessageForUser(mention); } await turnContext.Adapter.ContinueConversationAsync(_botId, conversationReference, async (context, token) => { var message = MessageFactory.Text(messageText); if (messageText.Contains(mention.Text)) { message.Entities.Add(mention); } await context.SendActivityAsync(message, token); }, cancellationToken); // build the envelope var submitCode = new SubmitCode(code); submitCode.SetToken(submissionToken); var envelope = KernelCommandEnvelope.Create(submitCode); var channel = ContentSubjectHelper.GetOrCreateChannel(submissionToken); EnvelopeHelper.StoreEnvelope(submissionToken, envelope); var cardSent = false; channel .Timeout(DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(1))) .Buffer(TimeSpan.FromSeconds(1)) .Subscribe( onNext: async formattedValues => { turnContext.Adapter.ContinueConversationAsync(_botId, conversationReference, (context, token) => { if (formattedValues.Count > 0) { var hasHtml = formattedValues.Any(f => f.MimeType == HtmlFormatter.MimeType); if (hasHtml) { if (!cardSent) { cardSent = true; var card = new HeroCard { Title = "Your output is too awesome 😎", Subtitle = "Use the viewer to see it.", Buttons = new List <CardAction> { new TaskModuleAction("Open Viewer", new { data = submissionToken }) }, }.ToAttachment(); var message = MessageFactory.Attachment(card); context.SendActivityAsync(message, token).Wait(); } } else { var content = string.Join("\n", formattedValues.Select(f => f.Value)); var message = MessageFactory.Text($"```\n{content.HtmlEncode()}"); context.SendActivityAsync(message, token).Wait(); } } return(Task.CompletedTask); }, cancellationToken).Wait(); }, onCompleted: async() => { await turnContext.Adapter.ContinueConversationAsync(_botId, conversationReference, async(context, token) => { await Task.Delay(1000); var message = MessageFactory.Text($"{mention.Text} all done here 👍"); message.Entities.Add(mention); await context.SendActivityAsync(message, token); }, cancellationToken); }, onError: async error => { await turnContext.Adapter.ContinueConversationAsync(_botId, conversationReference, async(context, token) => { await Task.Delay(1000); var message = MessageFactory.Text($@"{mention.Text} there were some issues 👎 :\n {error.Message}"); message.Entities.Add(mention); await context.SendActivityAsync(message, token); }, cancellationToken); }); user.IncrementCodeSubmissionCount(); await DotNetInteractiveProcessRunner.Instance.ExecuteEnvelope(submissionToken); } else { await turnContext.Adapter.ContinueConversationAsync(_botId, conversationReference, async (context, token) => { var message = MessageFactory.Text($"Sorry {mention.Text} cannot execute your code now. 😓"); message.Entities.Add(mention); await context.SendActivityAsync(message, token); }, cancellationToken); } } else if (string.IsNullOrWhiteSpace(DotNetInteractiveProcessRunner.Instance.SessionLanguage)) { var card = CardUtilities.CreateAdaptiveCardAttachment(CardJsonFiles.SelectLanguage); var attach = MessageFactory.Attachment(card); await turnContext.SendActivityAsync(attach, cancellationToken); } else if (content.Contains("👊")) { var mentioned = turnContext.Activity.GetMentions()?.FirstOrDefault(m => m.Mentioned.Id.EndsWith(_botId)); if (mentioned != null) { await turnContext.Adapter.ContinueConversationAsync(_botId, conversationReference, async (context, token) => { var message = MessageFactory.Text($"{mention.Text} back at you my friend! 👊"); message.Entities.Add(mention); await context.SendActivityAsync(message, token); }, cancellationToken); } } } else { var userAction = turnContext.Activity.Value; if (((JObject)userAction).Value <string>("userAction").Equals("SelectLanguage")) { if (string.IsNullOrWhiteSpace(DotNetInteractiveProcessRunner.Instance.SessionLanguage)) { var language = ((JObject)userAction).Value <string>("language"); DotNetInteractiveProcessRunner.Instance.SessionLanguage = language; var languageLabel = ((JObject)userAction).Value <string>("languageLabel"); var message = MessageFactory.Text($"All set. Let's write some {DotNetInteractiveProcessRunner.Instance.SessionLanguage} code together! 🤘🏻"); await turnContext.SendActivityAsync(message, cancellationToken); } } } }