public async Task deferred_command_can_produce_events(Language language) { var scheduler = CreateScheduler(); SetKernelLanguage(language); var command = new SubmitCode(@"#!html <p>hello!</p>", Kernel.Name); command.Properties["publish-internal-events"] = true; DeferCommand(command); var request = ZeroMQMessage.Create(new ExecuteRequest("display(2+2)")); var context = new JupyterRequestContext(JupyterMessageSender, request); await scheduler.Schedule(context); await context.Done().Timeout(20.Seconds()); JupyterMessageSender.PubSubMessages .OfType <DisplayData>() .Should() .Contain(dp => dp.Data["text/html"].ToString().Trim() == "<p>hello!</p>"); }
public async Task commands_targeting_compositeKernel_are_not_routed_to_childKernels() { var receivedOnFakeKernel = new List <IKernelCommand>(); using var kernel = new CompositeKernel { new FakeKernel("fake") { Handle = (kernelCommand, context) => { receivedOnFakeKernel.Add(kernelCommand); return(Task.CompletedTask); } } }; var submitCode = new SubmitCode("//command", kernel.Name); await kernel.SendAsync(submitCode); receivedOnFakeKernel.Should() .BeEmpty(); }
public async Task csharp_hover_text_is_returned_for_shadowing_variables(Language language) { SubmitCode declaration = null; SubmitCode shadowingDeclaration = null; using var kernel = CreateKernel(language); switch (language) { case Language.CSharp: declaration = new SubmitCode("var identifier = 1234;"); shadowingDeclaration = new SubmitCode("var identifier = \"one-two-three-four\";"); break; case Language.FSharp: declaration = new SubmitCode("let identifier = 1234"); shadowingDeclaration = new SubmitCode("let identifier = \"one-two-three-four\""); break; } await kernel.SendAsync(declaration); await kernel.SendAsync(shadowingDeclaration); var markupCode = "ident$$ifier"; MarkupTestFile.GetLineAndColumn(markupCode, out var code, out var line, out var column); var commandResult = await SendHoverRequest(kernel, code, line, column); commandResult .KernelEvents .ToSubscribedList() .Should() .ContainSingle <HoverTextProduced>() .Which .Content .Should() .ContainSingle(fv => fv.Value == "(field) string identifier"); }
public async Task When_SubmitCode_command_only_adds_packages_to_csharp_kernel_then_CommandHandled_event_is_raised() { var kernel = new CompositeKernel { new CSharpKernel().UseNugetDirective() }; var command = new SubmitCode("#r \"nuget:Microsoft.Extensions.Logging, 2.2.0\""); var result = await kernel.SendAsync(command); using var events = result.KernelEvents.ToSubscribedList(); events .First() .Should() .Match(e => e is DisplayedValueProduced && ((DisplayedValueProduced)e).Value.ToString().Contains("Installing")); events .Should() .Contain(e => e is DisplayedValueUpdated); events .Should() .ContainSingle(e => e is NuGetPackageAdded); events.OfType <NuGetPackageAdded>() .Single() .PackageReference .Should() .BeEquivalentTo(new NugetPackageReference("Microsoft.Extensions.Logging", "2.2.0")); events .Should() .ContainSingle(e => e is CommandHandled); }
public async Task can_cancel_user_loop_using_CancellationToken() { // todo: this test is flaky and timeouts in CI while (true) { using var kernel = CreateKernel(); var cancelCommand = new Cancel(); var commandToCancel = new SubmitCode(@" using Microsoft.DotNet.Interactive; var cancellationToken = KernelInvocationContext.Current.CancellationToken; while(!cancellationToken.IsCancellationRequested){ await Task.Delay(10); }", targetKernelName: "csharp"); try { var resultForCommandToCancel = kernel.SendAsync(commandToCancel); await kernel.SendAsync(cancelCommand).Timeout(10.Seconds()); var result = await resultForCommandToCancel.Timeout(10.Seconds()); var submitCodeEvents = result.KernelEvents.ToSubscribedList(); submitCodeEvents.Should() .ContainSingle <CommandFailed>() .Which .Command .Should() .Be(commandToCancel); break; } catch (TimeoutException) { } } }
private void AddDirectiveMiddlewareAndCommonCommandHandlers() { Pipeline.AddMiddleware( (command, context, next) => command switch { SubmitCode submitCode => HandleDirectivesAndSubmitCode( submitCode, context, next), LoadExtension loadExtension => HandleLoadExtension( loadExtension, context, next), DisplayValue displayValue => HandleDisplayValue( displayValue, context, next), UpdateDisplayedValue updateDisplayValue => HandleUpdateDisplayValue( updateDisplayValue, context, next), LoadExtensionsInDirectory loadExtensionsInDirectory => HandleLoadExtensionsInDirectory( loadExtensionsInDirectory, context, next), _ => next(command, context) });
public async Task Deferred_commands_on_composite_kernel_are_execute_on_first_submission() { var deferredCommandExecuted = false; var subKernel = new CSharpKernel(); using var compositeKernel = new CompositeKernel { subKernel }; compositeKernel.DefaultKernelName = subKernel.Name; var deferred = new SubmitCode("placeholder") { Handler = (command, context) => { deferredCommandExecuted = true; return(Task.CompletedTask); } }; compositeKernel.DeferCommand(deferred); var events = compositeKernel.KernelEvents.ToSubscribedList(); await compositeKernel.SendAsync(new SubmitCode("var x = 1;", targetKernelName : subKernel.Name)); deferredCommandExecuted.Should().Be(true); events .Select(e => e.GetType()) .Should() .ContainInOrder( typeof(CodeSubmissionReceived), typeof(CompleteCodeSubmissionReceived), typeof(CommandHandled)); }
public async Task Commands_sent_within_the_code_of_another_command_do_not_publish_CommandFailed_to_the_outer_result() { using var kernel = new CompositeKernel { new CSharpKernel("cs1"), new CSharpKernel("cs2") }; var kernelEvents = kernel.KernelEvents.ToSubscribedList(); var command = new SubmitCode($@" #!cs1 using {typeof(Kernel).Namespace}; using {typeof(KernelCommand).Namespace}; await Kernel.Root.SendAsync(new SubmitCode(""error"", ""cs2"")); "); await kernel.SendAsync(command); kernelEvents.Should() .ContainSingle <CommandSucceeded>(e => e.Command == command); kernelEvents .Should() .NotContain(e => e is CommandFailed); }
public async Task javascript_ProxyKernel_can_share_a_value_from_csharp() { using var kernel = new CompositeKernel { new CSharpKernel() }; kernel.DefaultKernelName = "csharp"; using var remoteKernel = new FakeRemoteKernel(); var receiver = new MultiplexingKernelCommandAndEventReceiver(remoteKernel.Receiver); using var host = new KernelHost(kernel, remoteKernel.Sender, receiver); var _ = host.ConnectAsync(); var kernelInfo = new KernelInfo("javascript", null, new Uri("kernel://remote/js")); var javascriptKernel = await host.CreateProxyKernelOnDefaultConnectorAsync(kernelInfo); javascriptKernel.UseValueSharing(new JavaScriptKernelValueDeclarer()); await kernel.SubmitCodeAsync("var csharpVariable = 123;"); var submitCode = new SubmitCode(@" #!javascript #!share --from csharp csharpVariable"); await kernel.SendAsync(submitCode); var remoteCommands = remoteKernel.Sender.Commands; remoteCommands.Should() .ContainSingle <SubmitCode>() .Which .Code .Should() .Be("csharpVariable = 123;"); }
//Not implemented: [InlineData(Language.FSharp)] public async Task it_can_load_script_files_using_load_directive_with_relative_path_after_command_changeWorkingDirectory(Language language) { var currentDirectory = Directory.GetCurrentDirectory(); DisposeAfterTest(() => Directory.SetCurrentDirectory(currentDirectory)); var kernel = CreateKernel(language); var absolutePathOneLevelHigher = Directory.GetParent(currentDirectory).FullName; await kernel.SendAsync(new ChangeWorkingDirectory(absolutePathOneLevelHigher)); var relativePath = Path.GetRelativePath(absolutePathOneLevelHigher, currentDirectory); var code = language switch { Language.CSharp => $"#load \"{relativePath}/RelativeLoadingSample.csx\"", Language.FSharp => $"#load \"{relativePath}/RelativeLoadingSample.fsx\"" }; var command = new SubmitCode(code); await kernel.SendAsync(command); KernelEvents.Should() .ContainSingle <StandardOutputValueProduced>(e => e.FormattedValues.Any(v => v.Value.Contains("hello!"))); }
public async Task Deferred_commands_on_composite_kernel_can_use_directives() { var deferredCommandExecuted = false; var subKernel = new CSharpKernel(); using var compositeKernel = new CompositeKernel { subKernel }; var customDirective = new Command("#!customDirective") { Handler = CommandHandler.Create(() => { deferredCommandExecuted = true; }) }; compositeKernel.AddDirective(customDirective); compositeKernel.DefaultKernelName = subKernel.Name; var deferred = new SubmitCode("#!customDirective"); compositeKernel.DeferCommand(deferred); var events = compositeKernel.KernelEvents.ToSubscribedList(); await compositeKernel.SendAsync(new SubmitCode("var x = 1;", targetKernelName : subKernel.Name)); deferredCommandExecuted.Should().Be(true); events .Select(e => e.GetType()) .Should() .ContainInOrder( typeof(CodeSubmissionReceived), typeof(CompleteCodeSubmissionReceived), typeof(CommandSucceeded)); }
public static IEnumerable <object[]> Events() { foreach (var @event in events()) { yield return(new object[] { @event }); } IEnumerable <KernelEvent> events() { var submitCode = new SubmitCode("123"); yield return(new CodeSubmissionReceived( submitCode)); yield return(new CommandFailed( "Oooops!", submitCode)); yield return(new CommandFailed( new InvalidOperationException("Oooops!"), submitCode, "oops")); yield return(new CommandSucceeded(submitCode)); yield return(new CompleteCodeSubmissionReceived(submitCode)); var requestCompletion = new RequestCompletions("Console.Wri", new LinePosition(0, 11)); yield return(new CompletionsProduced( new[] { new CompletionItem( "WriteLine", "Method", "WriteLine", "WriteLine", "WriteLine", "Writes the line") }, requestCompletion)); yield return(new CompletionRequestReceived(requestCompletion)); yield return(new DiagnosticLogEntryProduced("oops!", submitCode)); yield return(new DisplayedValueProduced( new HtmlString("<b>hi!</b>"), new SubmitCode("b(\"hi!\")", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/html", "<b>hi!</b>"), })); yield return(new DisplayedValueUpdated( new HtmlString("<b>hi!</b>"), "the-value-id", new SubmitCode("b(\"hi!\")", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/html", "<b>hi!</b>"), })); yield return(new ErrorProduced("oops!")); yield return(new IncompleteCodeSubmissionReceived(submitCode)); yield return(new InputRequested("prompt", submitCode)); var requestHoverTextCommand = new RequestHoverText("document-contents", new LinePosition(1, 2)); yield return(new HoverTextProduced( requestHoverTextCommand, new[] { new FormattedValue("text/markdown", "markdown") }, new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)))); yield return(new PackageAdded( new ResolvedPackageReference("ThePackage", "1.2.3", new[] { new FileInfo(Path.GetTempFileName()) }))); yield return(new PasswordRequested("password", submitCode)); yield return(new ReturnValueProduced( new HtmlString("<b>hi!</b>"), new SubmitCode("b(\"hi!\")", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/html", "<b>hi!</b>"), })); yield return(new StandardErrorValueProduced( "oops!", submitCode, new[] { new FormattedValue("text/plain", "oops!"), })); yield return(new StandardOutputValueProduced( 123, new SubmitCode("Console.Write(123);", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/plain", "123"), })); yield return(new WorkingDirectoryChanged( new DirectoryInfo("some/different/directory"), new ChangeWorkingDirectory(new DirectoryInfo("some/different/directory")))); } }
private async Task HandleSubmitCode( SubmitCode submitCode, KernelInvocationContext context) { CancellationTokenSource cancellationSource; lock (_cancellationSourceLock) { cancellationSource = _cancellationSource; } var codeSubmissionReceived = new CodeSubmissionReceived(submitCode); context.Publish(codeSubmissionReceived); var code = submitCode.Code; var isComplete = await IsCompleteSubmissionAsync(submitCode.Code); if (isComplete) { context.Publish(new CompleteCodeSubmissionReceived(submitCode)); } else { context.Publish(new IncompleteCodeSubmissionReceived(submitCode)); } if (submitCode.SubmissionType == SubmissionType.Diagnose) { return; } Exception exception = null; using var console = await ConsoleOutput.Capture(); using (console.SubscribeToStandardOutput(std => PublishOutput(std, context, submitCode))) using (console.SubscribeToStandardError(std => PublishError(std, context, submitCode))) { if (!cancellationSource.IsCancellationRequested) { try { if (ScriptState == null) { ScriptState = await CSharpScript.RunAsync( code, ScriptOptions, cancellationToken : cancellationSource.Token) .UntilCancelled(cancellationSource.Token); } else { ScriptState = await ScriptState.ContinueWithAsync( code, ScriptOptions, catchException : e => { exception = e; return(true); }, cancellationToken : cancellationSource.Token) .UntilCancelled(cancellationSource.Token); } } catch (CompilationErrorException cpe) { exception = new CodeSubmissionCompilationErrorException(cpe); } catch (Exception e) { exception = e; } } } if (!cancellationSource.IsCancellationRequested) { if (exception != null) { string message = null; if (exception is CodeSubmissionCompilationErrorException compilationError) { message = string.Join(Environment.NewLine, (compilationError.InnerException as CompilationErrorException)?.Diagnostics.Select(d => d.ToString()) ?? Enumerable.Empty <string>()); } context.Publish(new CommandFailed(exception, submitCode, message)); } else { if (ScriptState != null && HasReturnValue) { var formattedValues = FormattedValue.FromObject(ScriptState.ReturnValue); context.Publish( new ReturnValueProduced( ScriptState.ReturnValue, submitCode, formattedValues)); } context.Complete(); } } else { context.Publish(new CommandFailed(null, submitCode, "Command cancelled")); } }
public async Task SubmitCode(Kernel kernel, string submission, SubmissionType submissionType = SubmissionType.Run) { var command = new SubmitCode(submission, submissionType: submissionType); await kernel.SendAsync(command); }
public CompleteCodeSubmissionReceived(SubmitCode submitCode) : base(submitCode) { }
public async Task SubmitCode(KernelBase kernel, string codeFragment, SubmissionType submissionType = SubmissionType.Run) { var command = new SubmitCode(codeFragment, submissionType: submissionType); await kernel.SendAsync(command); }
public async Task Loads_native_dependencies_from_nugets() { using var kernel = CreateKernel(Language.CSharp); using var events = kernel.KernelEvents.ToSubscribedList(); var command = new SubmitCode(@" #r ""nuget:Microsoft.ML, 1.3.1"" using Microsoft.ML; using Microsoft.ML.Data; using System; class IrisData { public IrisData(float sepalLength, float sepalWidth, float petalLength, float petalWidth) { SepalLength = sepalLength; SepalWidth = sepalWidth; PetalLength = petalLength; PetalWidth = petalWidth; } public float SepalLength; public float SepalWidth; public float PetalLength; public float PetalWidth; } var data = new[] { new IrisData(1.4f, 1.3f, 2.5f, 4.5f), new IrisData(2.4f, 0.3f, 9.5f, 3.4f), new IrisData(3.4f, 4.3f, 1.6f, 7.5f), new IrisData(3.9f, 5.3f, 1.5f, 6.5f), }; MLContext mlContext = new MLContext(); var pipeline = mlContext.Transforms .Concatenate(""Features"", ""SepalLength"", ""SepalWidth"", ""PetalLength"", ""PetalWidth"") .Append(mlContext.Clustering.Trainers.KMeans(""Features"", numberOfClusters: 2)); try { pipeline.Fit(mlContext.Data.LoadFromEnumerable(data)); Console.WriteLine(""success""); } catch (Exception e) { Console.WriteLine(e); }"); await kernel.SendAsync(command); events .Should() .Contain(e => e is PackageAdded); events .Should() .ContainSingle <StandardOutputValueProduced>(e => e.Value.As <string>().Contains("success")); }
public static IEnumerable <object[]> Events() { foreach (var @event in events()) { yield return(new object[] { @event }); } IEnumerable <IKernelEvent> events() { var submitCode = new SubmitCode("123"); yield return(new CodeSubmissionReceived( submitCode)); yield return(new CommandFailed( "Oooops!", submitCode)); yield return(new CommandFailed( new InvalidOperationException("Oooops!"), submitCode, "oops")); yield return(new CommandHandled(submitCode)); yield return(new CompleteCodeSubmissionReceived(submitCode)); var requestCompletion = new RequestCompletion("Console.Wri", 11); yield return(new CompletionRequestCompleted( new[] { new CompletionItem( "WriteLine", "Method", "WriteLine", "WriteLine", "WriteLine", "Writes the line") }, requestCompletion)); yield return(new CompletionRequestReceived(requestCompletion)); yield return(new CurrentCommandCancelled(submitCode)); yield return(new DiagnosticLogEventProduced("oops!", submitCode)); yield return(new DisplayedValueProduced( new HtmlString("<b>hi!</b>"), new SubmitCode("b(\"hi!\")", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/html", "<b>hi!</b>"), })); yield return(new DisplayedValueUpdated( new HtmlString("<b>hi!</b>"), "the-value-id", new SubmitCode("b(\"hi!\")", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/html", "<b>hi!</b>"), })); yield return(new ErrorProduced("oops!")); yield return(new IncompleteCodeSubmissionReceived(submitCode)); yield return(new InputRequested("prompt", submitCode)); yield return(new PackageAdded( new ResolvedPackageReference("ThePackage", "1.2.3", new[] { new FileInfo(Path.GetTempFileName()) }))); yield return(new PasswordRequested("password", submitCode)); yield return(new ReturnValueProduced( new HtmlString("<b>hi!</b>"), new SubmitCode("b(\"hi!\")", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/html", "<b>hi!</b>"), })); yield return(new StandardErrorValueProduced( "oops!", submitCode, new[] { new FormattedValue("text/plain", "oops!"), })); yield return(new StandardOutputValueProduced( 123, new SubmitCode("Console.Write(123);", "csharp", SubmissionType.Run), new[] { new FormattedValue("text/plain", "123"), })); } }
public async Task HandleAsync(SubmitCode submitCode, KernelInvocationContext context) { var codeSubmissionReceived = new CodeSubmissionReceived(submitCode); context.Publish(codeSubmissionReceived); var code = submitCode.Code; var isComplete = await IsCompleteSubmissionAsync(submitCode.Code); if (isComplete) { context.Publish(new CompleteCodeSubmissionReceived(submitCode)); } else { context.Publish(new IncompleteCodeSubmissionReceived(submitCode)); } if (submitCode.SubmissionType == SubmissionType.Diagnose) { return; } Exception exception = null; string message = null; if (!context.CancellationToken.IsCancellationRequested) { try { await RunAsync( code, context.CancellationToken, e => { exception = e; return(true); }); } catch (CompilationErrorException cpe) { exception = new CodeSubmissionCompilationErrorException(cpe); } catch (Exception e) { exception = e; } } if (!context.CancellationToken.IsCancellationRequested) { var diagnostics = ImmutableArray <CodeAnalysis.Diagnostic> .Empty; // Check for a compilation failure if (exception is CodeSubmissionCompilationErrorException compilationError && compilationError.InnerException is CompilationErrorException innerCompilationException) { diagnostics = innerCompilationException.Diagnostics; // In the case of an error the diagnostics get attached to both the // DiagnosticsProduced and CommandFailed events. message = string.Join(Environment.NewLine, innerCompilationException.Diagnostics.Select(d => d.ToString()) ?? Enumerable.Empty <string>()); } else { diagnostics = ScriptState?.Script.GetCompilation().GetDiagnostics() ?? ImmutableArray <CodeAnalysis.Diagnostic> .Empty; } // Publish the compilation diagnostics. This doesn't include the exception. var kernelDiagnostics = diagnostics.Select(Diagnostic.FromCodeAnalysisDiagnostic).ToImmutableArray(); var formattedDiagnostics = diagnostics .Select(d => d.ToString()) .Select(text => new FormattedValue(PlainTextFormatter.MimeType, text)) .ToImmutableArray(); context.Publish(new DiagnosticsProduced(kernelDiagnostics, submitCode, formattedDiagnostics)); // Report the compilation failure or exception if (exception != null) { context.Fail(exception, message); } else { if (ScriptState != null && HasReturnValue) { var formattedValues = FormattedValue.FromObject(ScriptState.ReturnValue); context.Publish( new ReturnValueProduced( ScriptState.ReturnValue, submitCode, formattedValues)); } } }
protected override async Task HandleSubmitCode(SubmitCode command, KernelInvocationContext context) { await context.DisplayAsync( command.Code, HtmlFormatter.MimeType); }
#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); } } } }
public async Task Loads_native_dependencies_from_nugets() { using var kernel = new CompositeKernel { new CSharpKernel().UseNugetDirective(new NativeAssemblyLoadHelper()) }; var command = new SubmitCode(@"#r ""nuget:Microsoft.ML, 1.3.1"" using Microsoft.ML; using Microsoft.ML.Data; using System; class IrisData { public IrisData(float sepalLength, float sepalWidth, float petalLength, float petalWidth) { SepalLength = sepalLength; SepalWidth = sepalWidth; PetalLength = petalLength; PetalWidth = petalWidth; } public float SepalLength; public float SepalWidth; public float PetalLength; public float PetalWidth; } var data = new[] { new IrisData(1.4f, 1.3f, 2.5f, 4.5f), new IrisData(2.4f, 0.3f, 9.5f, 3.4f), new IrisData(3.4f, 4.3f, 1.6f, 7.5f), new IrisData(3.9f, 5.3f, 1.5f, 6.5f), }; MLContext mlContext = new MLContext(); var pipeline = mlContext.Transforms .Concatenate(""Features"", ""SepalLength"", ""SepalWidth"", ""PetalLength"", ""PetalWidth"") .Append(mlContext.Clustering.Trainers.KMeans(""Features"", numberOfClusters: 2)); try { pipeline.Fit(mlContext.Data.LoadFromEnumerable(data)); Console.WriteLine(""success""); } catch (Exception e) { Console.WriteLine(e); }", "csharp"); var result = await kernel.SendAsync(command); using var events = result.KernelEvents.ToSubscribedList(); events .Should() .ContainSingle(e => e is NuGetPackageAdded); events .Should() .Contain(e => e is DisplayedValueProduced && (((DisplayedValueProduced)e).Value as string).Contains("success")); }
public IReadOnlyList <IKernelCommand> SplitSubmission(SubmitCode submitCode) { var directiveParser = GetDirectiveParser(); var lines = new Queue <string>( submitCode.Code.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None)); var linesToForward = new List <string>(); var commands = new List <IKernelCommand>(); var packageCommands = new List <IKernelCommand>(); var commandWasSplit = false; while (lines.Count > 0) { var currentLine = lines.Dequeue(); if (currentLine.TrimStart().StartsWith("#")) { var parseResult = directiveParser.Parse(currentLine); var command = parseResult.CommandResult.Command; if (parseResult.Errors.Count == 0) { commandWasSplit = true; if (AccumulatedSubmission() is { } cmd) { commands.Add(cmd); } var runDirective = new DirectiveCommand(parseResult); if (command.Name == "#r" || command.Name == "#i") { packageCommands.Add(runDirective); } else { commands.Add(runDirective); } } else { if (command == parseResult.Parser.Configuration.RootCommand) { linesToForward.Add(currentLine); } else if (IsDirectiveSupportedByCompiler(command, parseResult)) { linesToForward.Add(currentLine); } else { commands.Clear(); commands.Add( new AnonymousKernelCommand((kernelCommand, context) => { var message = string.Join(Environment.NewLine, parseResult.Errors .Select(e => e.ToString())); context.Fail(message: message); return(Task.CompletedTask); })); } } } else { linesToForward.Add(currentLine); } } if (commandWasSplit) { if (AccumulatedSubmission() is { } command) { commands.Add(command); } } else { commands.Add(submitCode); } if (packageCommands.Count > 0) { var parseResult = directiveParser.Parse("#!nuget-restore"); packageCommands.Add(new DirectiveCommand(parseResult)); } return(packageCommands.Concat(commands).ToArray()); IKernelCommand AccumulatedSubmission() { if (linesToForward.Any()) { var code = string.Join(Environment.NewLine, linesToForward); linesToForward.Clear(); if (!string.IsNullOrWhiteSpace(code)) { return(new SubmitCode(code)); } } return(null); } }
protected override async Task HandleSubmitCode( SubmitCode submitCode, KernelInvocationContext context) { var codeSubmissionReceived = new CodeSubmissionReceived(submitCode); context.Publish(codeSubmissionReceived); var code = submitCode.Code; var isComplete = await IsCompleteSubmissionAsync(submitCode.Code); if (isComplete) { context.Publish(new CompleteCodeSubmissionReceived(submitCode)); } else { context.Publish(new IncompleteCodeSubmissionReceived(submitCode)); } if (submitCode.SubmissionType == SubmissionType.Diagnose) { return; } Exception exception = null; if (!context.CancellationToken.IsCancellationRequested) { try { await RunAsync( code, context.CancellationToken, e => { exception = e; return(true); }); } catch (CompilationErrorException cpe) { exception = new CodeSubmissionCompilationErrorException(cpe); } catch (Exception e) { exception = e; } } if (!context.CancellationToken.IsCancellationRequested) { if (exception != null) { string message = null; if (exception is CodeSubmissionCompilationErrorException compilationError) { message = string.Join(Environment.NewLine, (compilationError.InnerException as CompilationErrorException)?.Diagnostics.Select(d => d.ToString()) ?? Enumerable.Empty <string>()); } context.Fail(exception, message); } else { if (ScriptState != null && HasReturnValue) { var formattedValues = FormattedValue.FromObject(ScriptState.ReturnValue); context.Publish( new ReturnValueProduced( ScriptState.ReturnValue, submitCode, formattedValues)); } } } else { context.Fail(null, "Command cancelled"); } }
public IReadOnlyList <KernelCommand> SplitSubmission(SubmitCode submitCode) => SplitSubmission( submitCode, submitCode.Code, (languageNode, parent, kernelNameNode) => new SubmitCode(languageNode, submitCode.SubmissionType, parent, kernelNameNode));
public IReadOnlyList <IKernelCommand> SplitSubmission(SubmitCode submitCode) { var directiveParser = GetDirectiveParser(); var lines = new Queue <string>( submitCode.Code.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None)); var nonDirectiveLines = new List <string>(); var commands = new List <IKernelCommand>(); var hoistedCommands = new List <IKernelCommand>(); var commandWasSplit = false; while (lines.Count > 0) { var currentLine = lines.Dequeue(); if (string.IsNullOrWhiteSpace(currentLine)) { nonDirectiveLines.Add(currentLine); continue; } var parseResult = directiveParser.Parse(currentLine); var command = parseResult.CommandResult.Command; if (parseResult.Errors.Count == 0) { commandWasSplit = true; if (AccumulatedSubmission() is { } cmd) { commands.Add(cmd); } var runDirective = new AnonymousKernelCommand( (_, __) => parseResult.InvokeAsync()); if (command.Name == "#r") { hoistedCommands.Add(runDirective); } else { commands.Add(runDirective); } } else { if (command == parseResult.Parser.Configuration.RootCommand || command.Name == "#r") { nonDirectiveLines.Add(currentLine); } else { var message = string.Join(Environment.NewLine, parseResult.Errors .Select(e => e.ToString())); commands.Add(new DisplayError(message)); } } } if (commandWasSplit) { if (AccumulatedSubmission() is { } command) { commands.Add(command); } } else { commands.Add(submitCode); } if (hoistedCommands.Count > 0) { var parseResult = directiveParser.Parse("#!nuget-restore"); hoistedCommands.Add( new AnonymousKernelCommand( (_, __) => parseResult.InvokeAsync())); } return(hoistedCommands.Concat(commands).ToArray()); IKernelCommand AccumulatedSubmission() { if (nonDirectiveLines.Any()) { var code = string.Join(Environment.NewLine, nonDirectiveLines); nonDirectiveLines.Clear(); if (!string.IsNullOrWhiteSpace(code)) { return(new SubmitCode(code)); } } return(null); } }
public CodeSubmissionReceived(SubmitCode command) : base(command) { }
public Task HandleAsync(SubmitCode command, KernelInvocationContext context) => HandleSubmitCodeAsync(command, context);
private static CompositeKernel CreateKernel( string defaultKernelName, FrontendEnvironment frontendEnvironment, StartupOptions startupOptions, HttpProbingSettings httpProbingSettings) { var compositeKernel = new CompositeKernel(); compositeKernel.FrontendEnvironment = frontendEnvironment; compositeKernel.Add( new CSharpKernel() .UseDefaultFormatting() .UseNugetDirective() .UseKernelHelpers() .UseJupyterHelpers() .UseWho() .UseXplot() .UseMathAndLaTeX(), new[] { "c#", "C#" }); compositeKernel.Add( new FSharpKernel() .UseDefaultFormatting() .UseNugetDirective() .UseKernelHelpers() .UseWho() .UseDefaultNamespaces() .UseXplot() .UseMathAndLaTeX(), new[] { "f#", "F#" }); compositeKernel.Add( new PowerShellKernel() .UseJupyterHelpers() .UseXplot() .UseProfiles(), new[] { "pwsh" }); compositeKernel.Add( new JavaScriptKernel(), new[] { "js" }); compositeKernel.Add( new HtmlKernel()); var kernel = compositeKernel .UseDefaultMagicCommands() .UseLog() .UseAbout(); SetUpFormatters(frontendEnvironment, startupOptions); kernel.DefaultKernelName = defaultKernelName; if (startupOptions.EnableHttpApi) { kernel = kernel.UseHttpApi(startupOptions, httpProbingSettings); var enableHttp = new SubmitCode("#!enable-http", compositeKernel.Name); enableHttp.PublishInternalEvents(); kernel.DeferCommand(enableHttp); } return(kernel); }
public IReadOnlyList <KernelCommand> SplitSubmission(SubmitCode submitCode) { var commands = new List <KernelCommand>(); var nugetRestoreOnKernels = new HashSet <string>(); var hoistedCommandsIndex = 0; var tree = Parse(submitCode.Code, submitCode.TargetKernelName); var nodes = tree.GetRoot().ChildNodes.ToArray(); var targetKernelName = submitCode.TargetKernelName ?? KernelLanguage; foreach (var node in nodes) { switch (node) { case DirectiveNode directiveNode: var parseResult = directiveNode.GetDirectiveParseResult(); if (parseResult.Errors.Any()) { commands.Clear(); commands.Add( new AnonymousKernelCommand((kernelCommand, context) => { var message = string.Join(Environment.NewLine, parseResult.Errors .Select(e => e.ToString())); context.Fail(message: message); return(Task.CompletedTask); }, parent: submitCode.Parent)); break; } var directiveCommand = new DirectiveCommand( parseResult, submitCode.Parent, directiveNode); if (directiveNode is KernelNameDirectiveNode kernelNameNode) { targetKernelName = kernelNameNode.KernelName; } if (parseResult.CommandResult.Command.Name == "#r") { var value = parseResult.CommandResult.GetArgumentValueOrDefault <PackageReferenceOrFileInfo>("package"); if (value.Value is FileInfo) { AddHoistedCommand( new SubmitCode( directiveNode, submitCode.SubmissionType, submitCode.Parent)); } else { AddHoistedCommand(directiveCommand); nugetRestoreOnKernels.Add(targetKernelName); } } else if (parseResult.CommandResult.Command.Name == "#i") { directiveCommand.TargetKernelName = targetKernelName; AddHoistedCommand(directiveCommand); } else { commands.Add(directiveCommand); } break; case LanguageNode languageNode: commands.Add(new SubmitCode( languageNode, submitCode.SubmissionType, submitCode.Parent)); break; default: throw new ArgumentOutOfRangeException(nameof(node)); } } foreach (var kernelName in nugetRestoreOnKernels) { var kernel = _kernel.FindKernel(kernelName); if (kernel?.SubmissionParser.GetDirectiveParser() is {} parser) { var restore = new DirectiveCommand( parser.Parse("#!nuget-restore"), submitCode.Parent); AddHoistedCommand(restore); } } if (NoSplitWasNeeded(out var originalSubmission)) { return(originalSubmission); } var parent = submitCode.Parent ?? submitCode; foreach (var command in commands) { command.Parent = parent; } return(commands); void AddHoistedCommand(KernelCommand command) { commands.Insert(hoistedCommandsIndex++, command); } bool NoSplitWasNeeded(out IReadOnlyList <KernelCommand> splitSubmission) { if (commands.Count == 0) { splitSubmission = new[] { submitCode }; return(true); } if (commands.Count == 1) { if (commands[0] is SubmitCode sc) { if (submitCode.Code.Equals(sc.Code, StringComparison.Ordinal)) { splitSubmission = new[] { submitCode }; return(true); } } } splitSubmission = null; return(false); } }