db620d33df
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
115 lines
3.7 KiB
C#
115 lines
3.7 KiB
C#
// Copyright (c) Microsoft. All rights reserved.
|
|
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.AI;
|
|
using Moq;
|
|
|
|
namespace Microsoft.Agents.AI.LocalCodeAct.UnitTests;
|
|
|
|
public sealed class LocalCodeActProviderTests
|
|
{
|
|
private static readonly AIAgent s_mockAgent = new Mock<AIAgent>().Object;
|
|
|
|
private static AIContextProvider.InvokingContext NewInvokingContext() =>
|
|
new(s_mockAgent, session: null, new AIContext());
|
|
|
|
private static LocalCodeActProviderOptions Options() =>
|
|
new()
|
|
{
|
|
ValidationDisabled = true, // No subprocess will be launched in these tests
|
|
};
|
|
|
|
[Fact]
|
|
public async Task ProvideAIContextAsync_ReturnsExecuteCodeToolAndInstructionsAsync()
|
|
{
|
|
using var provider = new LocalCodeActProvider("/usr/bin/python3", Options());
|
|
|
|
var context = await provider.InvokingAsync(NewInvokingContext());
|
|
|
|
Assert.NotNull(context);
|
|
Assert.NotNull(context!.Tools);
|
|
var tools = context.Tools!.ToList();
|
|
Assert.Single(tools);
|
|
var function = Assert.IsAssignableFrom<AIFunction>(tools[0]);
|
|
Assert.Equal("execute_code", function.Name);
|
|
Assert.False(string.IsNullOrWhiteSpace(context.Instructions));
|
|
}
|
|
|
|
[Fact]
|
|
public void AddAndRemoveTools_RoundTrips()
|
|
{
|
|
using var provider = new LocalCodeActProvider("/usr/bin/python3", Options());
|
|
|
|
var tool = new TestTool("ping");
|
|
provider.AddTools(tool);
|
|
|
|
Assert.Contains(provider.GetTools(), t => t.Name == "ping");
|
|
|
|
provider.RemoveTools("ping");
|
|
Assert.DoesNotContain(provider.GetTools(), t => t.Name == "ping");
|
|
}
|
|
|
|
[Fact]
|
|
public void AddAndRemoveFileMounts_RoundTrips()
|
|
{
|
|
using var provider = new LocalCodeActProvider("/usr/bin/python3", Options());
|
|
|
|
var tempDir = System.IO.Directory.CreateTempSubdirectory("localcodeact-test-").FullName;
|
|
try
|
|
{
|
|
var mount = new FileMount(tempDir, "/app/data");
|
|
provider.AddFileMounts(mount);
|
|
|
|
Assert.Contains(provider.GetFileMounts(), m => m.MountPath == "/app/data");
|
|
|
|
provider.RemoveFileMounts("/app/data");
|
|
Assert.DoesNotContain(provider.GetFileMounts(), m => m.MountPath == "/app/data");
|
|
}
|
|
finally
|
|
{
|
|
System.IO.Directory.Delete(tempDir, recursive: true);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void ClearMethods_EmptyState()
|
|
{
|
|
using var provider = new LocalCodeActProvider("/usr/bin/python3", Options());
|
|
|
|
var tempDir1 = System.IO.Directory.CreateTempSubdirectory("localcodeact-test-").FullName;
|
|
var tempDir2 = System.IO.Directory.CreateTempSubdirectory("localcodeact-test-").FullName;
|
|
try
|
|
{
|
|
provider.AddTools(new TestTool("a"), new TestTool("b"));
|
|
provider.AddFileMounts(new FileMount(tempDir1, "/m/1"), new FileMount(tempDir2, "/m/2"));
|
|
|
|
provider.ClearTools();
|
|
provider.ClearFileMounts();
|
|
|
|
Assert.Empty(provider.GetTools());
|
|
Assert.Empty(provider.GetFileMounts());
|
|
}
|
|
finally
|
|
{
|
|
System.IO.Directory.Delete(tempDir1, recursive: true);
|
|
System.IO.Directory.Delete(tempDir2, recursive: true);
|
|
}
|
|
}
|
|
|
|
private sealed class TestTool : AIFunction
|
|
{
|
|
public TestTool(string name)
|
|
{
|
|
this.Name = name;
|
|
}
|
|
|
|
public override string Name { get; }
|
|
|
|
public override string Description => "test tool";
|
|
|
|
protected override ValueTask<object?> InvokeCoreAsync(AIFunctionArguments arguments, System.Threading.CancellationToken cancellationToken) =>
|
|
new((object?)null);
|
|
}
|
|
}
|