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);
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        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: ");
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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));
        }
Ejemplo n.º 12
0
#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);
                    }
                }
            }
        }