Skip to content

Commit db7bbfd

Browse files
LittleLittleCloudvictordibia
authored andcommitted
[.Net] Fix #2660 and add tests for AutoGen.DotnetInteractive (#2676)
* update * fix 2660 * remove unnecessary feed
1 parent 6b4e23a commit db7bbfd

11 files changed

+203
-106
lines changed

dotnet/AutoGen.sln

+8-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoGen.Mistral", "src\Auto
3333
EndProject
3434
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoGen.Mistral.Tests", "test\AutoGen.Mistral.Tests\AutoGen.Mistral.Tests.csproj", "{15441693-3659-4868-B6C1-B106F52FF3BA}"
3535
EndProject
36-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoGen.SemanticKernel.Tests", "test\AutoGen.SemanticKernel.Tests\AutoGen.SemanticKernel.Tests.csproj", "{1DFABC4A-8458-4875-8DCB-59F3802DAC65}"
36+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AutoGen.SemanticKernel.Tests", "test\AutoGen.SemanticKernel.Tests\AutoGen.SemanticKernel.Tests.csproj", "{1DFABC4A-8458-4875-8DCB-59F3802DAC65}"
37+
EndProject
38+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoGen.DotnetInteractive.Tests", "test\AutoGen.DotnetInteractive.Tests\AutoGen.DotnetInteractive.Tests.csproj", "{B61388CA-DC73-4B7F-A7B2-7B9A86C9229E}"
3739
EndProject
3840
Global
3941
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -93,6 +95,10 @@ Global
9395
{1DFABC4A-8458-4875-8DCB-59F3802DAC65}.Debug|Any CPU.Build.0 = Debug|Any CPU
9496
{1DFABC4A-8458-4875-8DCB-59F3802DAC65}.Release|Any CPU.ActiveCfg = Release|Any CPU
9597
{1DFABC4A-8458-4875-8DCB-59F3802DAC65}.Release|Any CPU.Build.0 = Release|Any CPU
98+
{B61388CA-DC73-4B7F-A7B2-7B9A86C9229E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
99+
{B61388CA-DC73-4B7F-A7B2-7B9A86C9229E}.Debug|Any CPU.Build.0 = Debug|Any CPU
100+
{B61388CA-DC73-4B7F-A7B2-7B9A86C9229E}.Release|Any CPU.ActiveCfg = Release|Any CPU
101+
{B61388CA-DC73-4B7F-A7B2-7B9A86C9229E}.Release|Any CPU.Build.0 = Release|Any CPU
96102
EndGlobalSection
97103
GlobalSection(SolutionProperties) = preSolution
98104
HideSolutionNode = FALSE
@@ -111,6 +117,7 @@ Global
111117
{6585D1A4-3D97-4D76-A688-1933B61AEB19} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
112118
{15441693-3659-4868-B6C1-B106F52FF3BA} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
113119
{1DFABC4A-8458-4875-8DCB-59F3802DAC65} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
120+
{B61388CA-DC73-4B7F-A7B2-7B9A86C9229E} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
114121
EndGlobalSection
115122
GlobalSection(ExtensibilityGlobals) = postSolution
116123
SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B}

dotnet/NuGet.config

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
<configuration>
33
<packageSources>
44
<clear />
5-
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
6-
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
75
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
86
</packageSources>
97
<disabledPackageSources />

dotnet/eng/Version.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<FluentAssertionVersion>6.8.0</FluentAssertionVersion>
1111
<XUnitVersion>2.4.2</XUnitVersion>
1212
<MicrosoftNETTestSdkVersion>17.7.0</MicrosoftNETTestSdkVersion>
13-
<MicrosoftDotnetInteractive>1.0.0-beta.23523.2</MicrosoftDotnetInteractive>
13+
<MicrosoftDotnetInteractive>1.0.0-beta.24229.4</MicrosoftDotnetInteractive>
1414
<MicrosoftSourceLinkGitHubVersion>8.0.0</MicrosoftSourceLinkGitHubVersion>
1515
<JsonSchemaVersion>4.0.0</JsonSchemaVersion>
1616
</PropertyGroup>

dotnet/src/AutoGen.DotnetInteractive/AutoGen.DotnetInteractive.csproj

+3-5
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,20 @@
1919
</PropertyGroup>
2020

2121
<ItemGroup>
22-
<PackageReference Include="Microsoft.DotNet.Interactive.VisualStudio" Version="$(MicrosoftDotnetInteractive)" />
22+
<PackageReference Include="Microsoft.DotNet.Interactive" Version="$(MicrosoftDotnetInteractive)" />
2323
</ItemGroup>
2424

2525
<ItemGroup>
2626
<EmbeddedResource Include="dotnet-tools.json" />
2727
<EmbeddedResource Include="RestoreInteractive.config" />
2828
</ItemGroup>
2929

30-
31-
<ItemGroup>
30+
<ItemGroup>
3231
<PackageReference Include="Azure.AI.OpenAI" Version="$(AzureOpenAIVersion)" />
3332
</ItemGroup>
3433

35-
3634
<ItemGroup>
37-
<ProjectReference Include="..\AutoGen\AutoGen.csproj" />
35+
<ProjectReference Include="..\AutoGen.Core\AutoGen.Core.csproj" />
3836
</ItemGroup>
3937

4038
</Project>

dotnet/src/AutoGen.DotnetInteractive/DotnetInteractiveFunction.cs

+36-35
Original file line numberDiff line numberDiff line change
@@ -12,57 +12,58 @@ namespace AutoGen.DotnetInteractive;
1212
public class DotnetInteractiveFunction : IDisposable
1313
{
1414
private readonly InteractiveService? _interactiveService = null;
15-
private string? _notebookPath;
15+
private string _notebookPath;
1616
private readonly KernelInfoCollection _kernelInfoCollection = new KernelInfoCollection();
1717

18+
/// <summary>
19+
/// Create an instance of <see cref="DotnetInteractiveFunction"/>"
20+
/// </summary>
21+
/// <param name="interactiveService">interactive service to use.</param>
22+
/// <param name="notebookPath">notebook path if provided.</param>
1823
public DotnetInteractiveFunction(InteractiveService interactiveService, string? notebookPath = null, bool continueFromExistingNotebook = false)
1924
{
2025
this._interactiveService = interactiveService;
21-
this._notebookPath = notebookPath;
26+
this._notebookPath = notebookPath ?? Path.GetTempPath() + "notebook.ipynb";
2227
this._kernelInfoCollection.Add(new KernelInfo("csharp"));
2328
this._kernelInfoCollection.Add(new KernelInfo("markdown"));
24-
25-
if (this._notebookPath != null)
29+
if (continueFromExistingNotebook == false)
2630
{
27-
if (continueFromExistingNotebook == false)
31+
// remove existing notebook
32+
if (File.Exists(this._notebookPath))
2833
{
29-
// remove existing notebook
30-
if (File.Exists(this._notebookPath))
31-
{
32-
File.Delete(this._notebookPath);
33-
}
34+
File.Delete(this._notebookPath);
35+
}
3436

35-
var document = new InteractiveDocument();
37+
var document = new InteractiveDocument();
3638

37-
using var stream = File.OpenWrite(_notebookPath);
38-
Notebook.Write(document, stream, this._kernelInfoCollection);
39-
stream.Flush();
40-
stream.Dispose();
41-
}
42-
else if (continueFromExistingNotebook == true && File.Exists(this._notebookPath))
39+
using var stream = File.OpenWrite(_notebookPath);
40+
Notebook.Write(document, stream, this._kernelInfoCollection);
41+
stream.Flush();
42+
stream.Dispose();
43+
}
44+
else if (continueFromExistingNotebook == true && File.Exists(this._notebookPath))
45+
{
46+
// load existing notebook
47+
using var readStream = File.OpenRead(this._notebookPath);
48+
var document = Notebook.Read(readStream, this._kernelInfoCollection);
49+
foreach (var cell in document.Elements)
4350
{
44-
// load existing notebook
45-
using var readStream = File.OpenRead(this._notebookPath);
46-
var document = Notebook.Read(readStream, this._kernelInfoCollection);
47-
foreach (var cell in document.Elements)
51+
if (cell.KernelName == "csharp")
4852
{
49-
if (cell.KernelName == "csharp")
50-
{
51-
var code = cell.Contents;
52-
this._interactiveService.SubmitCSharpCodeAsync(code, default).Wait();
53-
}
53+
var code = cell.Contents;
54+
this._interactiveService.SubmitCSharpCodeAsync(code, default).Wait();
5455
}
5556
}
56-
else
57-
{
58-
// create an empty notebook
59-
var document = new InteractiveDocument();
57+
}
58+
else
59+
{
60+
// create an empty notebook
61+
var document = new InteractiveDocument();
6062

61-
using var stream = File.OpenWrite(_notebookPath);
62-
Notebook.Write(document, stream, this._kernelInfoCollection);
63-
stream.Flush();
64-
stream.Dispose();
65-
}
63+
using var stream = File.OpenWrite(_notebookPath);
64+
Notebook.Write(document, stream, this._kernelInfoCollection);
65+
stream.Flush();
66+
stream.Dispose();
6667
}
6768
}
6869

dotnet/src/AutoGen.DotnetInteractive/InteractiveService.cs

+48-49
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Reactive.Linq;
66
using System.Reflection;
77
using Microsoft.DotNet.Interactive;
8-
using Microsoft.DotNet.Interactive.App.Connection;
98
using Microsoft.DotNet.Interactive.Commands;
109
using Microsoft.DotNet.Interactive.Connection;
1110
using Microsoft.DotNet.Interactive.Events;
@@ -41,7 +40,7 @@ public InteractiveService(string installingDirectory)
4140

4241
public async Task<bool> StartAsync(string workingDirectory, CancellationToken ct = default)
4342
{
44-
this.kernel = await this.CreateKernelAsync(workingDirectory, ct);
43+
this.kernel = await this.CreateKernelAsync(workingDirectory, true, ct);
4544
return true;
4645
}
4746

@@ -84,7 +83,51 @@ public async Task<bool> StartAsync(string workingDirectory, CancellationToken ct
8483
return await this.SubmitCommandAsync(command, ct);
8584
}
8685

87-
private async Task<Kernel> CreateKernelAsync(string workingDirectory, CancellationToken ct = default)
86+
public bool RestoreDotnetInteractive()
87+
{
88+
this.WriteLine("Restore dotnet interactive tool");
89+
// write RestoreInteractive.config from embedded resource to this.workingDirectory
90+
var assembly = Assembly.GetAssembly(typeof(InteractiveService))!;
91+
var resourceName = "AutoGen.DotnetInteractive.RestoreInteractive.config";
92+
using (var stream = assembly.GetManifestResourceStream(resourceName)!)
93+
using (var fileStream = File.Create(Path.Combine(this.installingDirectory, "RestoreInteractive.config")))
94+
{
95+
stream.CopyTo(fileStream);
96+
}
97+
98+
// write dotnet-tool.json from embedded resource to this.workingDirectory
99+
100+
resourceName = "AutoGen.DotnetInteractive.dotnet-tools.json";
101+
using (var stream2 = assembly.GetManifestResourceStream(resourceName)!)
102+
using (var fileStream2 = File.Create(Path.Combine(this.installingDirectory, "dotnet-tools.json")))
103+
{
104+
stream2.CopyTo(fileStream2);
105+
}
106+
107+
var psi = new ProcessStartInfo
108+
{
109+
FileName = "dotnet",
110+
Arguments = $"tool restore --configfile RestoreInteractive.config",
111+
WorkingDirectory = this.installingDirectory,
112+
RedirectStandardInput = true,
113+
RedirectStandardOutput = true,
114+
RedirectStandardError = true,
115+
UseShellExecute = false,
116+
CreateNoWindow = true,
117+
};
118+
119+
using var process = new Process { StartInfo = psi };
120+
process.OutputDataReceived += this.PrintProcessOutput;
121+
process.ErrorDataReceived += this.PrintProcessOutput;
122+
process.Start();
123+
process.BeginErrorReadLine();
124+
process.BeginOutputReadLine();
125+
process.WaitForExit();
126+
127+
return process.ExitCode == 0;
128+
}
129+
130+
private async Task<Kernel> CreateKernelAsync(string workingDirectory, bool restoreWhenFail = true, CancellationToken ct = default)
88131
{
89132
try
90133
{
@@ -139,13 +182,13 @@ await rootProxyKernel.SendAsync(
139182

140183
return compositeKernel;
141184
}
142-
catch (CommandLineInvocationException ex) when (ex.Message.Contains("Cannot find a tool in the manifest file that has a command named 'dotnet-interactive'"))
185+
catch (CommandLineInvocationException) when (restoreWhenFail)
143186
{
144187
var success = this.RestoreDotnetInteractive();
145188

146189
if (success)
147190
{
148-
return await this.CreateKernelAsync(workingDirectory, ct);
191+
return await this.CreateKernelAsync(workingDirectory, false, ct);
149192
}
150193

151194
throw;
@@ -176,50 +219,6 @@ private void WriteLine(string data)
176219
this.Output?.Invoke(this, data);
177220
}
178221

179-
private bool RestoreDotnetInteractive()
180-
{
181-
this.WriteLine("Restore dotnet interactive tool");
182-
// write RestoreInteractive.config from embedded resource to this.workingDirectory
183-
var assembly = Assembly.GetAssembly(typeof(InteractiveService))!;
184-
var resourceName = "AutoGen.DotnetInteractive.RestoreInteractive.config";
185-
using (var stream = assembly.GetManifestResourceStream(resourceName)!)
186-
using (var fileStream = File.Create(Path.Combine(this.installingDirectory, "RestoreInteractive.config")))
187-
{
188-
stream.CopyTo(fileStream);
189-
}
190-
191-
// write dotnet-tool.json from embedded resource to this.workingDirectory
192-
193-
resourceName = "AutoGen.DotnetInteractive.dotnet-tools.json";
194-
using (var stream2 = assembly.GetManifestResourceStream(resourceName)!)
195-
using (var fileStream2 = File.Create(Path.Combine(this.installingDirectory, "dotnet-tools.json")))
196-
{
197-
stream2.CopyTo(fileStream2);
198-
}
199-
200-
var psi = new ProcessStartInfo
201-
{
202-
FileName = "dotnet",
203-
Arguments = $"tool restore --configfile RestoreInteractive.config",
204-
WorkingDirectory = this.installingDirectory,
205-
RedirectStandardInput = true,
206-
RedirectStandardOutput = true,
207-
RedirectStandardError = true,
208-
UseShellExecute = false,
209-
CreateNoWindow = true,
210-
};
211-
212-
using var process = new Process { StartInfo = psi };
213-
process.OutputDataReceived += this.PrintProcessOutput;
214-
process.ErrorDataReceived += this.PrintProcessOutput;
215-
process.Start();
216-
process.BeginErrorReadLine();
217-
process.BeginOutputReadLine();
218-
process.WaitForExit();
219-
220-
return process.ExitCode == 0;
221-
}
222-
223222
private void PrintProcessOutput(object sender, DataReceivedEventArgs e)
224223
{
225224
if (!string.IsNullOrEmpty(e.Data))

dotnet/src/AutoGen.DotnetInteractive/dotnet-tools.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"isRoot": true,
44
"tools": {
55
"Microsoft.dotnet-interactive": {
6-
"version": "1.0.431302",
6+
"version": "1.0.522904",
77
"commands": [
88
"dotnet-interactive"
99
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>$(TestTargetFramework)</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<IsPackable>false</IsPackable>
7+
<GenerateDocumentationFile>True</GenerateDocumentationFile>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="ApprovalTests" Version="$(ApprovalTestVersion)" />
12+
<PackageReference Include="FluentAssertions" Version="$(FluentAssertionVersion)" />
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkVersion)" />
14+
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
15+
<PackageReference Include="xunit.runner.console" Version="$(XUnitVersion)" />
16+
<PackageReference Include="xunit.runner.visualstudio" Version="$(XUnitVersion)" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<ProjectReference Include="..\..\src\AutoGen.SourceGenerator\AutoGen.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
21+
<ProjectReference Include="..\AutoGen.Tests\AutoGen.Tests.csproj" />
22+
</ItemGroup>
23+
24+
</Project>

0 commit comments

Comments
 (0)