mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Merge branch 'main' into dev/dotnet_workflow/handoff_hitl
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- Central version prefix - applies to all nuget packages. -->
|
||||
<VersionPrefix>1.0.0</VersionPrefix>
|
||||
<RCNumber>6</RCNumber>
|
||||
<VersionPrefix>1.1.0</VersionPrefix>
|
||||
<RCNumber>1</RCNumber>
|
||||
<PackageVersion Condition="'$(IsReleaseCandidate)' == 'true'">$(VersionPrefix)-rc$(RCNumber)</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsReleaseCandidate)' != 'true' AND '$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix).260402.1</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsReleaseCandidate)' != 'true' AND '$(VersionSuffix)' == ''">$(VersionPrefix)-preview.260402.1</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsReleaseCandidate)' != 'true' AND '$(VersionSuffix)' != ''">$(VersionPrefix)-$(VersionSuffix).260410.1</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsReleaseCandidate)' != 'true' AND '$(VersionSuffix)' == ''">$(VersionPrefix)-preview.260410.1</PackageVersion>
|
||||
<PackageVersion Condition="'$(IsReleased)' == 'true'">$(VersionPrefix)</PackageVersion>
|
||||
<GitTag>1.0.0</GitTag>
|
||||
<GitTag>1.1.0</GitTag>
|
||||
|
||||
<Configurations>Debug;Release;Publish</Configurations>
|
||||
<IsPackable>true</IsPackable>
|
||||
|
||||
<!-- Package validation. Baseline Version should be the latest version available on NuGet. -->
|
||||
<PackageValidationBaselineVersion>1.0.0-rc5</PackageValidationBaselineVersion>
|
||||
<!-- Enable validation for RC packages and GA packages -->
|
||||
<EnablePackageValidation Condition="'$(IsReleaseCandidate)' == 'true' OR '$(IsReleased)' == 'true'">true</EnablePackageValidation>
|
||||
<PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
|
||||
<!-- Enable validation for GA packages -->
|
||||
<EnablePackageValidation Condition="'$(IsReleased)' == 'true'">true</EnablePackageValidation>
|
||||
<!-- Validate assembly attributes only for Publish builds -->
|
||||
<NoWarn Condition="'$(Configuration)' != 'Publish'">$(NoWarn);CP0003</NoWarn>
|
||||
<!-- Do not validate reference assemblies -->
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
|
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentRecord,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentReference,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentVersion,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Azure.AI.Projects.AgentVersionCreationOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.String,System.String,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentRecord,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentReference,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentVersion,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Azure.AI.Projects.AgentVersionCreationOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.String,System.String,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentRecord,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentReference,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentVersion,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Azure.AI.Projects.AgentVersionCreationOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.String,System.String,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentRecord,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentReference,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentVersion,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Azure.AI.Projects.AgentVersionCreationOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.String,System.String,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentRecord,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentReference,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.AsAIAgent(Azure.AI.Projects.AIProjectClient,Azure.AI.Projects.OpenAI.AgentVersion,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Azure.AI.Projects.AgentVersionCreationOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.CreateAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.String,System.String,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,Microsoft.Agents.AI.ChatClientAgentOptions,System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Azure.AI.Projects.AzureAIProjectChatClientExtensions.GetAIAgentAsync(Azure.AI.Projects.AIProjectClient,System.String,System.Collections.Generic.IList{Microsoft.Extensions.AI.AITool},System.Func{Microsoft.Extensions.AI.IChatClient,Microsoft.Extensions.AI.IChatClient},System.IServiceProvider,System.Threading.CancellationToken)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.AzureAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
|
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:OpenAI.Assistants.OpenAIAssistantClientExtensions</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.OpenAI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.OpenAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:OpenAI.Assistants.OpenAIAssistantClientExtensions</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.OpenAI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.OpenAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:OpenAI.Assistants.OpenAIAssistantClientExtensions</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.OpenAI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.OpenAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:OpenAI.Assistants.OpenAIAssistantClientExtensions</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.OpenAI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.OpenAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:OpenAI.Assistants.OpenAIAssistantClientExtensions</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.OpenAI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.OpenAI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
|
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.Workflows.Declarative.AzureAgentProvider.get_OpenAIClientOptions</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.Workflows.Declarative.AzureAgentProvider.get_OpenAIClientOptions</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.Workflows.Declarative.AzureAgentProvider.get_OpenAIClientOptions</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.Workflows.Declarative.AzureAgentProvider.get_OpenAIClientOptions</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.Workflows.Declarative.AzureAgentProvider.get_OpenAIClientOptions</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.Workflows.Declarative.Foundry.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
@@ -43,27 +43,6 @@
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.get_SimulateServiceStoredChatHistory</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.set_SimulateServiceStoredChatHistory(System.Boolean)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Extensions.AI.ChatClientBuilderExtensions.UseServiceStoredChatHistorySimulation(Microsoft.Extensions.AI.ChatClientBuilder)</Target>
|
||||
<Left>lib/net10.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net10.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.AgentInlineSkill.#ctor(Microsoft.Agents.AI.AgentSkillFrontmatter,System.String)</Target>
|
||||
@@ -106,27 +85,6 @@
|
||||
<Right>lib/net472/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.get_SimulateServiceStoredChatHistory</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.set_SimulateServiceStoredChatHistory(System.Boolean)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Extensions.AI.ChatClientBuilderExtensions.UseServiceStoredChatHistorySimulation(Microsoft.Extensions.AI.ChatClientBuilder)</Target>
|
||||
<Left>lib/net472/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net472/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.AgentInlineSkill.#ctor(Microsoft.Agents.AI.AgentSkillFrontmatter,System.String)</Target>
|
||||
@@ -169,27 +127,6 @@
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.get_SimulateServiceStoredChatHistory</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.set_SimulateServiceStoredChatHistory(System.Boolean)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Extensions.AI.ChatClientBuilderExtensions.UseServiceStoredChatHistorySimulation(Microsoft.Extensions.AI.ChatClientBuilder)</Target>
|
||||
<Left>lib/net8.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net8.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.AgentInlineSkill.#ctor(Microsoft.Agents.AI.AgentSkillFrontmatter,System.String)</Target>
|
||||
@@ -232,27 +169,6 @@
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.get_SimulateServiceStoredChatHistory</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.set_SimulateServiceStoredChatHistory(System.Boolean)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Extensions.AI.ChatClientBuilderExtensions.UseServiceStoredChatHistorySimulation(Microsoft.Extensions.AI.ChatClientBuilder)</Target>
|
||||
<Left>lib/net9.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/net9.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.AgentInlineSkill.#ctor(Microsoft.Agents.AI.AgentSkillFrontmatter,System.String)</Target>
|
||||
@@ -295,25 +211,4 @@
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.get_SimulateServiceStoredChatHistory</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Agents.AI.ChatClientAgentOptions.set_SimulateServiceStoredChatHistory(System.Boolean)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Microsoft.Extensions.AI.ChatClientBuilderExtensions.UseServiceStoredChatHistorySimulation(Microsoft.Extensions.AI.ChatClientBuilder)</Target>
|
||||
<Left>lib/netstandard2.0/Microsoft.Agents.AI.dll</Left>
|
||||
<Right>lib/netstandard2.0/Microsoft.Agents.AI.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
@@ -32,15 +32,15 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
private const string SkillFileName = "SKILL.md";
|
||||
private const int MaxSearchDepth = 2;
|
||||
|
||||
// "." means the skill directory root itself (no sub-folder descent constraint)
|
||||
private const string RootFolderIndicator = ".";
|
||||
// "." means the skill directory root itself (no subdirectory descent constraint)
|
||||
private const string RootDirectoryIndicator = ".";
|
||||
|
||||
private static readonly string[] s_defaultScriptExtensions = [".py", ".js", ".sh", ".ps1", ".cs", ".csx"];
|
||||
private static readonly string[] s_defaultResourceExtensions = [".md", ".json", ".yaml", ".yml", ".csv", ".xml", ".txt"];
|
||||
|
||||
// Standard sub-folder names per https://agentskills.io/specification#directory-structure
|
||||
private static readonly string[] s_defaultScriptFolders = ["scripts"];
|
||||
private static readonly string[] s_defaultResourceFolders = ["references", "assets"];
|
||||
// Standard subdirectory names per https://agentskills.io/specification#directory-structure
|
||||
private static readonly string[] s_defaultScriptDirectories = ["scripts"];
|
||||
private static readonly string[] s_defaultResourceDirectories = ["references", "assets"];
|
||||
|
||||
// Matches YAML frontmatter delimited by "---" lines. Group 1 = content between delimiters.
|
||||
// Multiline makes ^/$ match line boundaries; Singleline makes . match newlines across the block.
|
||||
@@ -63,8 +63,8 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
private readonly IEnumerable<string> _skillPaths;
|
||||
private readonly HashSet<string> _allowedResourceExtensions;
|
||||
private readonly HashSet<string> _allowedScriptExtensions;
|
||||
private readonly IReadOnlyList<string> _scriptFolders;
|
||||
private readonly IReadOnlyList<string> _resourceFolders;
|
||||
private readonly IReadOnlyList<string> _scriptDirectories;
|
||||
private readonly IReadOnlyList<string> _resourceDirectories;
|
||||
private readonly AgentFileSkillScriptRunner? _scriptRunner;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
@@ -111,13 +111,13 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
options?.AllowedScriptExtensions ?? s_defaultScriptExtensions,
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
this._scriptFolders = options?.ScriptFolders is not null
|
||||
? [.. ValidateAndNormalizeFolderNames(options.ScriptFolders, this._logger)]
|
||||
: s_defaultScriptFolders;
|
||||
this._scriptDirectories = options?.ScriptDirectories is not null
|
||||
? [.. ValidateAndNormalizeDirectoryNames(options.ScriptDirectories, this._logger)]
|
||||
: s_defaultScriptDirectories;
|
||||
|
||||
this._resourceFolders = options?.ResourceFolders is not null
|
||||
? [.. ValidateAndNormalizeFolderNames(options.ResourceFolders, this._logger)]
|
||||
: s_defaultResourceFolders;
|
||||
this._resourceDirectories = options?.ResourceDirectories is not null
|
||||
? [.. ValidateAndNormalizeDirectoryNames(options.ResourceDirectories, this._logger)]
|
||||
: s_defaultResourceDirectories;
|
||||
|
||||
this._scriptRunner = scriptRunner;
|
||||
}
|
||||
@@ -303,12 +303,12 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans configured resource folders within a skill directory for resource files matching the configured extensions.
|
||||
/// Scans configured resource directories within a skill directory for resource files matching the configured extensions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, scans <c>references/</c> and <c>assets/</c> sub-folders as specified by the
|
||||
/// By default, scans <c>references/</c> and <c>assets/</c> subdirectories as specified by the
|
||||
/// <see href="https://agentskills.io/specification">Agent Skills specification</see>.
|
||||
/// Configure <see cref="AgentFileSkillsSourceOptions.ResourceFolders"/> to scan different or
|
||||
/// Configure <see cref="AgentFileSkillsSourceOptions.ResourceDirectories"/> to scan different or
|
||||
/// additional directories, including <c>"."</c> for the skill root itself.
|
||||
/// Each file is validated against path-traversal and symlink-escape checks; unsafe files are skipped.
|
||||
/// </remarks>
|
||||
@@ -316,14 +316,14 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
{
|
||||
var resources = new List<AgentFileSkillResource>();
|
||||
|
||||
foreach (string folder in this._resourceFolders.Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
foreach (string directory in this._resourceDirectories.Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
bool isRootFolder = string.Equals(folder, RootFolderIndicator, StringComparison.Ordinal);
|
||||
bool isRootDirectory = string.Equals(directory, RootDirectoryIndicator, StringComparison.Ordinal);
|
||||
|
||||
// GetFullPath normalizes mixed separators (e.g. "C:\skill\scripts/f1" → "C:\skill\scripts\f1")
|
||||
string targetDirectory = isRootFolder
|
||||
string targetDirectory = isRootDirectory
|
||||
? skillDirectoryFullPath
|
||||
: Path.GetFullPath(Path.Combine(skillDirectoryFullPath, folder)) + Path.DirectorySeparatorChar;
|
||||
: Path.GetFullPath(Path.Combine(skillDirectoryFullPath, directory)) + Path.DirectorySeparatorChar;
|
||||
|
||||
if (!Directory.Exists(targetDirectory))
|
||||
{
|
||||
@@ -331,13 +331,13 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
}
|
||||
|
||||
// Directory-level symlink check: skip if targetDirectory (or any intermediate
|
||||
// segment) is a reparse point. The root folder is excluded — it's a caller-supplied
|
||||
// segment) is a reparse point. The root directory is excluded — it's a caller-supplied
|
||||
// trusted path, and the security boundary guards files within it, not the path itself.
|
||||
if (!isRootFolder && HasSymlinkInPath(targetDirectory, skillDirectoryFullPath))
|
||||
if (!isRootDirectory && HasSymlinkInPath(targetDirectory, skillDirectoryFullPath))
|
||||
{
|
||||
if (this._logger.IsEnabled(LogLevel.Warning))
|
||||
{
|
||||
LogResourceSymlinkFolder(this._logger, skillName, SanitizePathForLog(folder));
|
||||
LogResourceSymlinkDirectory(this._logger, skillName, SanitizePathForLog(directory));
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -380,7 +380,7 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
// e.g. "references/../../../etc/shadow" → "/etc/shadow"
|
||||
string resolvedFilePath = Path.GetFullPath(filePath);
|
||||
|
||||
// Path containment: reject if the resolved path escapes the target folder.
|
||||
// Path containment: reject if the resolved path escapes the target directory.
|
||||
// e.g. "/etc/shadow".StartsWith("/skills/myskill/references/") → false → skip
|
||||
if (!resolvedFilePath.StartsWith(targetDirectory, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -416,12 +416,12 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans configured script folders within a skill directory for script files matching the configured extensions.
|
||||
/// Scans configured script directories within a skill directory for script files matching the configured extensions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, scans the <c>scripts/</c> sub-folder as specified by the
|
||||
/// By default, scans the <c>scripts/</c> subdirectory as specified by the
|
||||
/// <see href="https://agentskills.io/specification">Agent Skills specification</see>.
|
||||
/// Configure <see cref="AgentFileSkillsSourceOptions.ScriptFolders"/> to scan different or
|
||||
/// Configure <see cref="AgentFileSkillsSourceOptions.ScriptDirectories"/> to scan different or
|
||||
/// additional directories, including <c>"."</c> for the skill root itself.
|
||||
/// Each file is validated against path-traversal and symlink-escape checks; unsafe files are skipped.
|
||||
/// </remarks>
|
||||
@@ -429,14 +429,14 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
{
|
||||
var scripts = new List<AgentFileSkillScript>();
|
||||
|
||||
foreach (string folder in this._scriptFolders.Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
foreach (string directory in this._scriptDirectories.Distinct(StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
bool isRootFolder = string.Equals(folder, RootFolderIndicator, StringComparison.Ordinal);
|
||||
bool isRootDirectory = string.Equals(directory, RootDirectoryIndicator, StringComparison.Ordinal);
|
||||
|
||||
// GetFullPath normalizes mixed separators (e.g. "C:\skill\scripts/f1" → "C:\skill\scripts\f1")
|
||||
string targetDirectory = isRootFolder
|
||||
string targetDirectory = isRootDirectory
|
||||
? skillDirectoryFullPath
|
||||
: Path.GetFullPath(Path.Combine(skillDirectoryFullPath, folder)) + Path.DirectorySeparatorChar;
|
||||
: Path.GetFullPath(Path.Combine(skillDirectoryFullPath, directory)) + Path.DirectorySeparatorChar;
|
||||
|
||||
if (!Directory.Exists(targetDirectory))
|
||||
{
|
||||
@@ -444,13 +444,13 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
}
|
||||
|
||||
// Directory-level symlink check: skip if targetDirectory (or any intermediate
|
||||
// segment) is a reparse point. The root folder is excluded — it's a caller-supplied
|
||||
// segment) is a reparse point. The root directory is excluded — it's a caller-supplied
|
||||
// trusted path, and the security boundary guards files within it, not the path itself.
|
||||
if (!isRootFolder && HasSymlinkInPath(targetDirectory, skillDirectoryFullPath))
|
||||
if (!isRootDirectory && HasSymlinkInPath(targetDirectory, skillDirectoryFullPath))
|
||||
{
|
||||
if (this._logger.IsEnabled(LogLevel.Warning))
|
||||
{
|
||||
LogScriptSymlinkFolder(this._logger, skillName, SanitizePathForLog(folder));
|
||||
LogScriptSymlinkDirectory(this._logger, skillName, SanitizePathForLog(directory));
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -480,7 +480,7 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
// e.g. "scripts/../../../etc/shadow" → "/etc/shadow"
|
||||
string resolvedFilePath = Path.GetFullPath(filePath);
|
||||
|
||||
// Path containment: reject if the resolved path escapes the target folder.
|
||||
// Path containment: reject if the resolved path escapes the target directory.
|
||||
// e.g. "/etc/shadow".StartsWith("/skills/myskill/scripts/") → false → skip
|
||||
if (!resolvedFilePath.StartsWith(targetDirectory, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -541,8 +541,8 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normalizes a relative path or folder name by stripping a leading "./"/".\",
|
||||
/// trimming trailing directory separators, and replacing backslashes with forward
|
||||
/// Normalizes a relative path or directory name by stripping a leading "./"/".\",
|
||||
/// trimming trailing separators, and replacing backslashes with forward
|
||||
/// slashes.
|
||||
/// </summary>
|
||||
private static string NormalizePath(string path)
|
||||
@@ -602,36 +602,36 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<string> ValidateAndNormalizeFolderNames(IEnumerable<string> folders, ILogger logger)
|
||||
private static IEnumerable<string> ValidateAndNormalizeDirectoryNames(IEnumerable<string> directories, ILogger logger)
|
||||
{
|
||||
foreach (string folder in folders)
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(folder))
|
||||
if (string.IsNullOrWhiteSpace(directory))
|
||||
{
|
||||
throw new ArgumentException("Folder names must not be null or whitespace.", nameof(folders));
|
||||
throw new ArgumentException("Directory names must not be null or whitespace.", nameof(directories));
|
||||
}
|
||||
|
||||
// "." is valid — it means the skill root directory.
|
||||
if (string.Equals(folder, RootFolderIndicator, StringComparison.Ordinal))
|
||||
if (string.Equals(directory, RootDirectoryIndicator, StringComparison.Ordinal))
|
||||
{
|
||||
yield return folder;
|
||||
yield return directory;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reject absolute paths and any path segments that escape upward.
|
||||
if (Path.IsPathRooted(folder) || ContainsParentTraversalSegment(folder))
|
||||
if (Path.IsPathRooted(directory) || ContainsParentTraversalSegment(directory))
|
||||
{
|
||||
LogFolderNameSkippedInvalid(logger, folder);
|
||||
LogDirectoryNameSkippedInvalid(logger, directory);
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return NormalizePath(folder);
|
||||
yield return NormalizePath(directory);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ContainsParentTraversalSegment(string folder)
|
||||
private static bool ContainsParentTraversalSegment(string directory)
|
||||
{
|
||||
foreach (string segment in folder.Split('/', '\\'))
|
||||
foreach (string segment in directory.Split('/', '\\'))
|
||||
{
|
||||
if (segment == "..")
|
||||
{
|
||||
@@ -666,8 +666,8 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping resource in skill '{SkillName}': '{ResourcePath}' is a symlink that resolves outside the skill directory")]
|
||||
private static partial void LogResourceSymlinkEscape(ILogger logger, string skillName, string resourcePath);
|
||||
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping resource folder '{FolderName}' in skill '{SkillName}': folder path contains a symlink")]
|
||||
private static partial void LogResourceSymlinkFolder(ILogger logger, string skillName, string folderName);
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping resource directory '{DirectoryName}' in skill '{SkillName}': directory path contains a symlink")]
|
||||
private static partial void LogResourceSymlinkDirectory(ILogger logger, string skillName, string directoryName);
|
||||
|
||||
[LoggerMessage(LogLevel.Debug, "Skipping file '{FilePath}' in skill '{SkillName}': extension '{Extension}' is not in the allowed list")]
|
||||
private static partial void LogResourceSkippedExtension(ILogger logger, string skillName, string filePath, string extension);
|
||||
@@ -678,9 +678,9 @@ internal sealed partial class AgentFileSkillsSource : AgentSkillsSource
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping script in skill '{SkillName}': '{ScriptPath}' is a symlink that resolves outside the skill directory")]
|
||||
private static partial void LogScriptSymlinkEscape(ILogger logger, string skillName, string scriptPath);
|
||||
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping script folder '{FolderName}' in skill '{SkillName}': folder path contains a symlink")]
|
||||
private static partial void LogScriptSymlinkFolder(ILogger logger, string skillName, string folderName);
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping script directory '{DirectoryName}' in skill '{SkillName}': directory path contains a symlink")]
|
||||
private static partial void LogScriptSymlinkDirectory(ILogger logger, string skillName, string directoryName);
|
||||
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping invalid folder name '{FolderName}': must be a relative path with no '..' segments")]
|
||||
private static partial void LogFolderNameSkippedInvalid(ILogger logger, string folderName);
|
||||
[LoggerMessage(LogLevel.Warning, "Skipping invalid directory name '{DirectoryName}': must be a relative path with no '..' segments")]
|
||||
private static partial void LogDirectoryNameSkippedInvalid(ILogger logger, string directoryName);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public sealed class AgentFileSkillsSourceOptions
|
||||
public IEnumerable<string>? AllowedScriptExtensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets relative folder paths to scan for script files within each skill directory.
|
||||
/// Gets or sets relative directory paths to scan for script files within each skill directory.
|
||||
/// Values may be single-segment names (e.g., <c>"scripts"</c>) or multi-segment relative
|
||||
/// paths (e.g., <c>"sub/scripts"</c>). Use <c>"."</c> to include files directly at the
|
||||
/// skill root. Leading <c>"./"</c> prefixes, trailing separators, and backslashes are
|
||||
@@ -42,10 +42,10 @@ public sealed class AgentFileSkillsSourceOptions
|
||||
/// <see href="https://agentskills.io/specification">Agent Skills specification</see>).
|
||||
/// When set, replaces the defaults entirely.
|
||||
/// </summary>
|
||||
public IEnumerable<string>? ScriptFolders { get; set; }
|
||||
public IEnumerable<string>? ScriptDirectories { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets relative folder paths to scan for resource files within each skill directory.
|
||||
/// Gets or sets relative directory paths to scan for resource files within each skill directory.
|
||||
/// Values may be single-segment names (e.g., <c>"references"</c>) or multi-segment relative
|
||||
/// paths (e.g., <c>"sub/resources"</c>). Use <c>"."</c> to include files directly at the
|
||||
/// skill root. Leading <c>"./"</c> prefixes, trailing separators, and backslashes are
|
||||
@@ -55,5 +55,5 @@ public sealed class AgentFileSkillsSourceOptions
|
||||
/// <see href="https://agentskills.io/specification">Agent Skills specification</see>).
|
||||
/// When set, replaces the defaults entirely.
|
||||
/// </summary>
|
||||
public IEnumerable<string>? ResourceFolders { get; set; }
|
||||
public IEnumerable<string>? ResourceDirectories { get; set; }
|
||||
}
|
||||
|
||||
+18
-18
@@ -116,8 +116,8 @@ public sealed class AgentFileSkillsSourceScriptTests : IDisposable
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ScriptsOutsideScriptsDir_AreNotDiscoveredAsync()
|
||||
{
|
||||
// Arrange — scripts outside configured folders are not discovered; only files directly
|
||||
// inside the configured folder are picked up (no subdirectory recursion)
|
||||
// Arrange — scripts outside configured directories are not discovered; only files directly
|
||||
// inside the configured directory are picked up (no subdirectory recursion)
|
||||
string skillDir = CreateSkillDir(this._testRoot, "root-scripts", "Root scripts skill", "Body.");
|
||||
CreateFile(skillDir, "convert.py", "print('root')");
|
||||
CreateFile(skillDir, "tools/helper.sh", "echo 'helper'");
|
||||
@@ -126,7 +126,7 @@ public sealed class AgentFileSkillsSourceScriptTests : IDisposable
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync(CancellationToken.None);
|
||||
|
||||
// Assert — neither file is in the default scripts/ folder, so no scripts are discovered
|
||||
// Assert — neither file is in the default scripts/ directory, so no scripts are discovered
|
||||
Assert.Single(skills);
|
||||
Assert.Empty(skills[0].Scripts!);
|
||||
}
|
||||
@@ -229,18 +229,18 @@ public sealed class AgentFileSkillsSourceScriptTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ScriptFoldersWithNestedPath_DiscoversScriptsAsync()
|
||||
public async Task GetSkillsAsync_ScriptDirectoriesWithNestedPath_DiscoversScriptsAsync()
|
||||
{
|
||||
// Arrange — ScriptFolders configured with a multi-segment relative path (f1/f2/f3)
|
||||
string skillDir = CreateSkillDir(this._testRoot, "nested-script-skill", "Nested script folder", "Body.");
|
||||
// Arrange — ScriptDirectories configured with a multi-segment relative path (f1/f2/f3)
|
||||
string skillDir = CreateSkillDir(this._testRoot, "nested-script-skill", "Nested script directory", "Body.");
|
||||
CreateFile(skillDir, "f1/f2/f3/run.py", "print('nested')");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ScriptFolders = ["f1/f2/f3"] });
|
||||
new AgentFileSkillsSourceOptions { ScriptDirectories = ["f1/f2/f3"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync(CancellationToken.None);
|
||||
|
||||
// Assert — script file inside the deeply nested folder is discovered
|
||||
// Assert — script file inside the deeply nested directory is discovered
|
||||
Assert.Single(skills);
|
||||
Assert.Single(skills[0].Scripts!);
|
||||
Assert.Equal("f1/f2/f3/run.py", skills[0].Scripts![0].Name);
|
||||
@@ -250,29 +250,29 @@ public sealed class AgentFileSkillsSourceScriptTests : IDisposable
|
||||
[InlineData("./scripts")]
|
||||
[InlineData("./scripts/f1")]
|
||||
[InlineData("./scripts/f1", "./f2")]
|
||||
public async Task GetSkillsAsync_ScriptFolderWithDotSlashPrefix_DiscoversScriptsAsync(params string[] folders)
|
||||
public async Task GetSkillsAsync_ScriptDirectoryWithDotSlashPrefix_DiscoversScriptsAsync(params string[] directories)
|
||||
{
|
||||
// Arrange — "./"-prefixed folders are equivalent to their counterparts without the prefix;
|
||||
// Arrange — "./"-prefixed directories are equivalent to their counterparts without the prefix;
|
||||
// the leading "./" is transparently normalized by Path.GetFullPath during file enumeration.
|
||||
string skillDir = CreateSkillDir(this._testRoot, "dotslash-script-skill", "Dot-slash prefix", "Body.");
|
||||
foreach (string folder in folders)
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string folderWithoutDotSlash = folder.Substring(2); // strip "./"
|
||||
CreateFile(skillDir, $"{folderWithoutDotSlash}/run.py", "print('dotslash')");
|
||||
string directoryWithoutDotSlash = directory.Substring(2); // strip "./"
|
||||
CreateFile(skillDir, $"{directoryWithoutDotSlash}/run.py", "print('dotslash')");
|
||||
}
|
||||
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ScriptFolders = folders });
|
||||
new AgentFileSkillsSourceOptions { ScriptDirectories = directories });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync(CancellationToken.None);
|
||||
|
||||
// Assert — scripts are discovered with names identical to using folders without "./"
|
||||
// Assert — scripts are discovered with names identical to using directories without "./"
|
||||
Assert.Single(skills);
|
||||
Assert.Equal(folders.Length, skills[0].Scripts!.Count);
|
||||
foreach (string folder in folders)
|
||||
Assert.Equal(directories.Length, skills[0].Scripts!.Count);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string expectedName = $"{folder.Substring(2)}/run.py";
|
||||
string expectedName = $"{directory.Substring(2)}/run.py";
|
||||
Assert.Contains(skills[0].Scripts!, s => s.Name == expectedName);
|
||||
}
|
||||
}
|
||||
|
||||
+65
-65
@@ -199,7 +199,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_FilesWithMatchingExtensions_DiscoveredAsResourcesAsync()
|
||||
{
|
||||
// Arrange — create resource files in spec-defined sub-folders
|
||||
// Arrange — create resource files in spec-defined subdirectories
|
||||
string skillDir = Path.Combine(this._testRoot, "resource-skill");
|
||||
string refsDir = Path.Combine(skillDir, "references");
|
||||
string assetsDir = Path.Combine(skillDir, "assets");
|
||||
@@ -226,7 +226,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_FilesWithNonMatchingExtensions_NotDiscoveredAsync()
|
||||
{
|
||||
// Arrange — create a file with an extension not in the default list inside a spec folder
|
||||
// Arrange — create a file with an extension not in the default list inside a spec directory
|
||||
string skillDir = Path.Combine(this._testRoot, "ext-skill");
|
||||
string refsDir = Path.Combine(skillDir, "references");
|
||||
Directory.CreateDirectory(refsDir);
|
||||
@@ -300,7 +300,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_CustomResourceExtensions_UsedForDiscoveryAsync()
|
||||
{
|
||||
// Arrange — use a source with custom extensions; files placed in spec folder
|
||||
// Arrange — use a source with custom extensions; files placed in spec directory
|
||||
string skillDir = Path.Combine(this._testRoot, "custom-ext-skill");
|
||||
string refsDir = Path.Combine(skillDir, "references");
|
||||
Directory.CreateDirectory(refsDir);
|
||||
@@ -364,7 +364,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ResourceInSkillRoot_NotDiscoveredByDefaultAsync()
|
||||
{
|
||||
// Arrange — resource files directly in the skill directory (not in a spec sub-folder)
|
||||
// Arrange — resource files directly in the skill directory (not in a spec subdirectory)
|
||||
string skillDir = Path.Combine(this._testRoot, "root-resource-skill");
|
||||
Directory.CreateDirectory(skillDir);
|
||||
File.WriteAllText(Path.Combine(skillDir, "guide.md"), "guide content");
|
||||
@@ -377,15 +377,15 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — root-level files are NOT discovered unless "." is in ResourceFolders
|
||||
// Assert — root-level files are NOT discovered unless "." is in ResourceDirectories
|
||||
Assert.Single(skills);
|
||||
Assert.Empty(skills[0].Resources!);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ResourceInSkillRoot_DiscoveredWhenRootFolderConfiguredAsync()
|
||||
public async Task GetSkillsAsync_ResourceInSkillRoot_DiscoveredWhenRootDirectoryConfiguredAsync()
|
||||
{
|
||||
// Arrange — "." in ResourceFolders opts into root-level resource discovery
|
||||
// Arrange — "." in ResourceDirectories opts into root-level resource discovery
|
||||
string skillDir = Path.Combine(this._testRoot, "root-opt-in-skill");
|
||||
Directory.CreateDirectory(skillDir);
|
||||
File.WriteAllText(Path.Combine(skillDir, "guide.md"), "guide content");
|
||||
@@ -394,7 +394,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: root-opt-in-skill\ndescription: Root opt-in\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = ["references", "assets", "."] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = ["references", "assets", "."] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
@@ -408,31 +408,31 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ResourceInNonSpecFolder_NotDiscoveredByDefaultAsync()
|
||||
public async Task GetSkillsAsync_ResourceInNonSpecDirectory_NotDiscoveredByDefaultAsync()
|
||||
{
|
||||
// Arrange — resource in a non-spec folder (neither references/ nor assets/)
|
||||
// Arrange — resource in a non-spec directory (neither references/ nor assets/)
|
||||
string skillDir = Path.Combine(this._testRoot, "non-spec-skill");
|
||||
string customDir = Path.Combine(skillDir, "docs");
|
||||
Directory.CreateDirectory(customDir);
|
||||
File.WriteAllText(Path.Combine(customDir, "readme.md"), "docs content");
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: non-spec-skill\ndescription: Non-spec folder\n---\nBody.");
|
||||
"---\nname: non-spec-skill\ndescription: Non-spec directory\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor);
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — non-spec folders are not scanned by default
|
||||
// Assert — non-spec directories are not scanned by default
|
||||
Assert.Single(skills);
|
||||
Assert.Empty(skills[0].Resources!);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_CustomResourceFolders_ReplacesDefaultsAsync()
|
||||
public async Task GetSkillsAsync_CustomResourceDirectories_ReplacesDefaultsAsync()
|
||||
{
|
||||
// Arrange — custom ResourceFolders replaces the spec defaults
|
||||
string skillDir = Path.Combine(this._testRoot, "custom-folder-skill");
|
||||
// Arrange — custom ResourceDirectories replaces the spec defaults
|
||||
string skillDir = Path.Combine(this._testRoot, "custom-directory-skill");
|
||||
string customDir = Path.Combine(skillDir, "docs");
|
||||
string refsDir = Path.Combine(skillDir, "references");
|
||||
Directory.CreateDirectory(customDir);
|
||||
@@ -441,9 +441,9 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
File.WriteAllText(Path.Combine(refsDir, "ref.md"), "ref content");
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: custom-folder-skill\ndescription: Custom folder\n---\nBody.");
|
||||
"---\nname: custom-directory-skill\ndescription: Custom directory\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = ["docs"] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = ["docs"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
@@ -518,7 +518,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[Fact]
|
||||
public async Task ReadSkillResourceAsync_ValidResource_ReturnsContentAsync()
|
||||
{
|
||||
// Arrange — create a skill with a resource file discovered from the references folder
|
||||
// Arrange — create a skill with a resource file discovered from the references directory
|
||||
string skillDir = this.CreateSkillDirectory("read-skill", "A skill", "See docs for details.");
|
||||
string refsDir = Path.Combine(skillDir, "references");
|
||||
Directory.CreateDirectory(refsDir);
|
||||
@@ -614,12 +614,12 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_SymlinkedResourceFolder_SkipsWithoutEnumeratingAsync()
|
||||
public async Task GetSkillsAsync_SymlinkedResourceDirectory_SkipsWithoutEnumeratingAsync()
|
||||
{
|
||||
// Arrange — references/ is a symlink pointing outside the skill directory.
|
||||
// The directory-level check should skip it entirely (no file enumeration),
|
||||
// so even files with valid extensions in the target are not discovered.
|
||||
string skillDir = Path.Combine(this._testRoot, "symlink-folder-skip");
|
||||
string skillDir = Path.Combine(this._testRoot, "symlink-directory-skip");
|
||||
string assetsDir = Path.Combine(skillDir, "assets");
|
||||
Directory.CreateDirectory(assetsDir);
|
||||
File.WriteAllText(Path.Combine(assetsDir, "legit.md"), "legit content");
|
||||
@@ -642,21 +642,21 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: symlink-folder-skip\ndescription: Symlinked folder skip\n---\nBody.");
|
||||
"---\nname: symlink-directory-skip\ndescription: Symlinked directory skip\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor);
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — only assets/legit.md is found; the symlinked references/ folder is skipped entirely
|
||||
var skill = skills.FirstOrDefault(s => s.Frontmatter.Name == "symlink-folder-skip");
|
||||
// Assert — only assets/legit.md is found; the symlinked references/ directory is skipped entirely
|
||||
var skill = skills.FirstOrDefault(s => s.Frontmatter.Name == "symlink-directory-skip");
|
||||
Assert.NotNull(skill);
|
||||
Assert.Single(skill.Resources!);
|
||||
Assert.Equal("assets/legit.md", skill.Resources![0].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_SymlinkedScriptFolder_SkipsWithoutEnumeratingAsync()
|
||||
public async Task GetSkillsAsync_SymlinkedScriptDirectory_SkipsWithoutEnumeratingAsync()
|
||||
{
|
||||
// Arrange — scripts/ is a symlink pointing outside the skill directory.
|
||||
// The directory-level check should skip it entirely.
|
||||
@@ -679,22 +679,22 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: symlink-script-skip\ndescription: Symlinked script folder\n---\nBody.");
|
||||
"---\nname: symlink-script-skip\ndescription: Symlinked script directory\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor);
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — skill loads but scripts from the symlinked folder are not discovered
|
||||
// Assert — skill loads but scripts from the symlinked directory are not discovered
|
||||
var skill = skills.FirstOrDefault(s => s.Frontmatter.Name == "symlink-script-skip");
|
||||
Assert.NotNull(skill);
|
||||
Assert.Empty(skill.Scripts!);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_SymlinkedIntermediateSegment_SkipsCustomFolderAsync()
|
||||
public async Task GetSkillsAsync_SymlinkedIntermediateSegment_SkipsCustomDirectoryAsync()
|
||||
{
|
||||
// Arrange — custom resource folder "sub/resources" where "sub" is a symlink.
|
||||
// Arrange — custom resource directory "sub/resources" where "sub" is a symlink.
|
||||
// The directory-level HasSymlinkInPath check should detect the intermediate symlink.
|
||||
string skillDir = Path.Combine(this._testRoot, "symlink-intermediate");
|
||||
Directory.CreateDirectory(skillDir);
|
||||
@@ -720,12 +720,12 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
var source = new AgentFileSkillsSource(
|
||||
this._testRoot,
|
||||
s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = ["sub/resources"] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = ["sub/resources"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — the symlinked intermediate segment causes the folder to be skipped
|
||||
// Assert — the symlinked intermediate segment causes the directory to be skipped
|
||||
var skill = skills.FirstOrDefault(s => s.Frontmatter.Name == "symlink-intermediate");
|
||||
Assert.NotNull(skill);
|
||||
Assert.Empty(skill.Resources!);
|
||||
@@ -900,11 +900,11 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[InlineData("sub/../escape")]
|
||||
[InlineData("/absolute")]
|
||||
[InlineData("\\absolute")]
|
||||
public void Constructor_InvalidFolderName_SkipsInvalidFolders(string badFolder)
|
||||
public void Constructor_InvalidDirectoryName_SkipsInvalidDirectories(string badDirectory)
|
||||
{
|
||||
// Arrange & Act — invalid folders are skipped with a warning rather than throwing
|
||||
var source1 = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ScriptFolders = [badFolder] });
|
||||
var source2 = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ResourceFolders = [badFolder] });
|
||||
// Arrange & Act — invalid directories are skipped with a warning rather than throwing
|
||||
var source1 = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ScriptDirectories = [badDirectory] });
|
||||
var source2 = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ResourceDirectories = [badDirectory] });
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(source1);
|
||||
@@ -915,54 +915,54 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
public void Constructor_NullOrWhitespaceFolderName_ThrowsArgumentException(string? badFolder)
|
||||
public void Constructor_NullOrWhitespaceDirectoryName_ThrowsArgumentException(string? badDirectory)
|
||||
{
|
||||
// Arrange & Act & Assert — null/whitespace is a contract violation, not a config error
|
||||
Assert.Throws<ArgumentException>(() => new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ScriptFolders = [badFolder!] }));
|
||||
Assert.Throws<ArgumentException>(() => new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ResourceFolders = [badFolder!] }));
|
||||
Assert.Throws<ArgumentException>(() => new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ScriptDirectories = [badDirectory!] }));
|
||||
Assert.Throws<ArgumentException>(() => new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ResourceDirectories = [badDirectory!] }));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("scripts")]
|
||||
[InlineData("my-scripts")]
|
||||
[InlineData("sub/folder")]
|
||||
[InlineData("sub/directory")]
|
||||
[InlineData(".")]
|
||||
[InlineData("./scripts")]
|
||||
[InlineData("./scripts/f1")]
|
||||
[InlineData("my..scripts")]
|
||||
public void Constructor_ValidFolderName_DoesNotThrow(string validFolder)
|
||||
public void Constructor_ValidDirectoryName_DoesNotThrow(string validDirectory)
|
||||
{
|
||||
// Arrange & Act & Assert
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ScriptFolders = [validFolder] });
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor, new AgentFileSkillsSourceOptions { ScriptDirectories = [validDirectory] });
|
||||
Assert.NotNull(source);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_DuplicateFoldersAfterNormalization_NoDuplicateResourcesAsync()
|
||||
public async Task GetSkillsAsync_DuplicateDirectoriesAfterNormalization_NoDuplicateResourcesAsync()
|
||||
{
|
||||
// Arrange — "references" and "./references" refer to the same directory;
|
||||
// after normalization they should be deduplicated so resources appear only once.
|
||||
string skillDir = Path.Combine(this._testRoot, "dedup-folder-skill");
|
||||
string skillDir = Path.Combine(this._testRoot, "dedup-directory-skill");
|
||||
string refsDir = Path.Combine(skillDir, "references");
|
||||
Directory.CreateDirectory(refsDir);
|
||||
File.WriteAllText(Path.Combine(refsDir, "FAQ.md"), "FAQ content");
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: dedup-folder-skill\ndescription: Dedup test\n---\nBody.");
|
||||
"---\nname: dedup-directory-skill\ndescription: Dedup test\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = ["references", "./references"] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = ["references", "./references"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — only one copy of the resource despite two equivalent folder entries
|
||||
// Assert — only one copy of the resource despite two equivalent directory entries
|
||||
Assert.Single(skills);
|
||||
Assert.Single(skills[0].Resources!);
|
||||
Assert.Equal("references/FAQ.md", skills[0].Resources![0].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_TrailingSlashFolderNormalized_NoDuplicateResourcesAsync()
|
||||
public async Task GetSkillsAsync_TrailingSlashDirectoryNormalized_NoDuplicateResourcesAsync()
|
||||
{
|
||||
// Arrange — "references/" should be normalized to "references"
|
||||
string skillDir = Path.Combine(this._testRoot, "trailing-slash-skill");
|
||||
@@ -973,7 +973,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: trailing-slash-skill\ndescription: Trailing slash test\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = ["references", "references/"] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = ["references", "references/"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
@@ -985,7 +985,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_BackslashFolderNormalized_NoDuplicateScriptsAsync()
|
||||
public async Task GetSkillsAsync_BackslashDirectoryNormalized_NoDuplicateScriptsAsync()
|
||||
{
|
||||
// Arrange — ".\\scripts" should be normalized to "scripts"
|
||||
string skillDir = Path.Combine(this._testRoot, "backslash-skill");
|
||||
@@ -996,7 +996,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: backslash-skill\ndescription: Backslash test\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ScriptFolders = ["scripts", ".\\scripts"] });
|
||||
new AgentFileSkillsSourceOptions { ScriptDirectories = ["scripts", ".\\scripts"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
@@ -1010,48 +1010,48 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
[Theory]
|
||||
[InlineData("./references")]
|
||||
[InlineData("./assets/docs")]
|
||||
public async Task GetSkillsAsync_ResourceFolderWithDotSlashPrefix_DiscoversResourcesAsync(string folder)
|
||||
public async Task GetSkillsAsync_ResourceDirectoryWithDotSlashPrefix_DiscoversResourcesAsync(string directory)
|
||||
{
|
||||
// Arrange — "./references" and "./assets/docs" are equivalent to "references" and "assets/docs";
|
||||
// the leading "./" is transparently normalized by Path.GetFullPath during file enumeration.
|
||||
string folderWithoutDotSlash = folder.Substring(2); // strip "./"
|
||||
string directoryWithoutDotSlash = directory.Substring(2); // strip "./"
|
||||
string skillDir = Path.Combine(this._testRoot, "dotslash-res-skill");
|
||||
string targetDir = Path.Combine(skillDir, folderWithoutDotSlash.Replace('/', Path.DirectorySeparatorChar));
|
||||
string targetDir = Path.Combine(skillDir, directoryWithoutDotSlash.Replace('/', Path.DirectorySeparatorChar));
|
||||
Directory.CreateDirectory(targetDir);
|
||||
File.WriteAllText(Path.Combine(targetDir, "data.json"), "{}");
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: dotslash-res-skill\ndescription: Dot-slash prefix\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = [folder] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = [directory] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — the resource is discovered with a name identical to using the folder without "./"
|
||||
// Assert — the resource is discovered with a name identical to using the directory without "./"
|
||||
Assert.Single(skills);
|
||||
Assert.Single(skills[0].Resources!);
|
||||
Assert.Equal($"{folderWithoutDotSlash}/data.json", skills[0].Resources![0].Name);
|
||||
Assert.Equal($"{directoryWithoutDotSlash}/data.json", skills[0].Resources![0].Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ResourceFoldersWithNestedPath_DiscoversResourcesAsync()
|
||||
public async Task GetSkillsAsync_ResourceDirectoriesWithNestedPath_DiscoversResourcesAsync()
|
||||
{
|
||||
// Arrange — ResourceFolders configured with a multi-segment relative path (f1/f2/f3)
|
||||
string skillDir = Path.Combine(this._testRoot, "nested-folder-skill");
|
||||
// Arrange — ResourceDirectories configured with a multi-segment relative path (f1/f2/f3)
|
||||
string skillDir = Path.Combine(this._testRoot, "nested-directory-skill");
|
||||
string nestedDir = Path.Combine(skillDir, "f1", "f2", "f3");
|
||||
Directory.CreateDirectory(nestedDir);
|
||||
File.WriteAllText(Path.Combine(nestedDir, "data.json"), "{}");
|
||||
File.WriteAllText(
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: nested-folder-skill\ndescription: Nested folder\n---\nBody.");
|
||||
"---\nname: nested-directory-skill\ndescription: Nested directory\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ResourceFolders = ["f1/f2/f3"] });
|
||||
new AgentFileSkillsSourceOptions { ResourceDirectories = ["f1/f2/f3"] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
|
||||
// Assert — resource file inside the deeply nested folder is discovered
|
||||
// Assert — resource file inside the deeply nested directory is discovered
|
||||
Assert.Single(skills);
|
||||
var skill = skills[0];
|
||||
Assert.Single(skill.Resources!);
|
||||
@@ -1107,9 +1107,9 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_ScriptInSkillRoot_DiscoveredWhenRootFolderConfiguredAsync()
|
||||
public async Task GetSkillsAsync_ScriptInSkillRoot_DiscoveredWhenRootDirectoryConfiguredAsync()
|
||||
{
|
||||
// Arrange — script file directly in the skill directory with ScriptFolders = ["."]
|
||||
// Arrange — script file directly in the skill directory with ScriptDirectories = ["."]
|
||||
string skillDir = Path.Combine(this._testRoot, "root-script-skill");
|
||||
Directory.CreateDirectory(skillDir);
|
||||
File.WriteAllText(Path.Combine(skillDir, "run.py"), "print('hello')");
|
||||
@@ -1117,7 +1117,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
Path.Combine(skillDir, "SKILL.md"),
|
||||
"---\nname: root-script-skill\ndescription: Root script\n---\nBody.");
|
||||
var source = new AgentFileSkillsSource(this._testRoot, s_noOpExecutor,
|
||||
new AgentFileSkillsSourceOptions { ScriptFolders = ["."] });
|
||||
new AgentFileSkillsSourceOptions { ScriptDirectories = ["."] });
|
||||
|
||||
// Act
|
||||
var skills = await source.GetSkillsAsync();
|
||||
@@ -1131,7 +1131,7 @@ public sealed class FileAgentSkillLoaderTests : IDisposable
|
||||
|
||||
#if NET
|
||||
[Fact]
|
||||
public async Task GetSkillsAsync_SymlinkedFileInRealFolder_SkipsSymlinkedFileAsync()
|
||||
public async Task GetSkillsAsync_SymlinkedFileInRealDirectory_SkipsSymlinkedFileAsync()
|
||||
{
|
||||
// Arrange — references/ is a real directory, but one file inside it is a symlink
|
||||
// pointing outside the skill directory. The per-file symlink check should skip it.
|
||||
|
||||
Reference in New Issue
Block a user