Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions dotnet/src/Microsoft.Agents.AI/Skills/AgentSkillsProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -162,7 +162,7 @@ public AgentSkillsProvider(AgentSkillsSource source, AgentSkillsProviderOptions?
this._options = options;
this._logger = (loggerFactory ?? NullLoggerFactory.Instance).CreateLogger<AgentSkillsProvider>();

if (options?.SkillsInstructionPrompt is string prompt)
if ((options?.IncludeSkillInstructions ?? true) && options?.SkillsInstructionPrompt is string prompt)
{
ValidatePromptTemplate(prompt, nameof(options));
}
Expand Down Expand Up @@ -260,6 +260,11 @@ private IList<AIFunction> BuildTools(IList<AgentSkill> skills, bool hasScripts,

private string? BuildSkillsInstructions(IList<AgentSkill> skills, bool includeScriptInstructions, bool includeResourceInstructions)
{
if (this._options?.IncludeSkillInstructions == false)
{
return null;
}

string promptTemplate = this._options?.SkillsInstructionPrompt ?? DefaultSkillsInstructionPrompt;

var sb = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -139,6 +139,17 @@ public AgentSkillsProviderBuilder UseScriptApproval(bool enabled = true)
return this;
}

/// <summary>
/// Enables or disables including skill instructions in the system prompt.
/// </summary>
/// <param name="enabled">Whether to include skill instructions. Defaults to <see langword="true"/>.</param>
/// <returns>This builder instance for chaining.</returns>
public AgentSkillsProviderBuilder IncludeSkillInstructions(bool enabled = true)
{
this.GetOrCreateOptions().IncludeSkillInstructions = enabled;
return this;
}

/// <summary>
/// Sets the runner for file-based skill scripts.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

using System.Diagnostics.CodeAnalysis;
using Microsoft.Shared.DiagnosticIds;
Expand Down Expand Up @@ -34,4 +34,12 @@ public sealed class AgentSkillsProviderOptions
/// Set to <see langword="true"/> to rebuild tools and instructions on every invocation.
/// </summary>
public bool DisableCaching { get; set; }

/// <summary>
/// Gets or sets a value indicating whether skill instructions should be included in the system prompt.
/// When <see langword="true"/> (the default), skill names and descriptions are added
/// to the system prompt to guide the model on when to use specific skills.
/// Set to <see langword="false"/> to skip including these instructions in the prompt.
/// </summary>
public bool IncludeSkillInstructions { get; set; } = true;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -182,6 +182,23 @@ public void Build_UseOptions_ConfiguresOptions()
Assert.NotNull(provider);
}

[Fact]
public void Build_IncludeSkillInstructions_ConfiguresOptions()
{
// Arrange
var source = new TestAgentSkillsSource(
new TestAgentSkill("test", "Test", "Instructions."));

// Act
var provider = new AgentSkillsProviderBuilder()
.UseSource(source)
.IncludeSkillInstructions(false)
.Build();

// Assert
Assert.NotNull(provider);
}

[Fact]
public async Task Build_WithMultipleCustomSources_AggregatesAllAsync()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft. All rights reserved.
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -851,6 +851,42 @@ public async Task Constructor_InlineSkills_DeduplicatesAsync()
Assert.Contains("First instructions.", content!.ToString()!);
}

[Fact]
public async Task InvokingAsync_IncludeSkillInstructionsFalse_ReturnsNullInstructionsAsync()
{
// Arrange
this.CreateSkill("skip-skill", "Skip test", "Body.");
var options = new AgentSkillsProviderOptions { IncludeSkillInstructions = false };
var provider = new AgentSkillsProvider(new AgentFileSkillsSource(this._testRoot, s_noOpExecutor), options);
var inputContext = new AIContext { Instructions = "Base instructions" };
var invokingContext = new AIContextProvider.InvokingContext(this._agent, session: null, inputContext);

// Act
var result = await provider.InvokingAsync(invokingContext, CancellationToken.None);

// Assert
Assert.Equal("Base instructions", result.Instructions); // Should not have changed
Assert.NotNull(result.Tools);
Assert.Contains(result.Tools!, t => t.Name == "load_skill");
}

[Fact]
public void Constructor_IncludeSkillInstructionsFalse_SkipsPromptValidation()
{
// Arrange — invalid prompt (missing placeholders)
var options = new AgentSkillsProviderOptions
{
IncludeSkillInstructions = false,
SkillsInstructionPrompt = "Invalid prompt without placeholders"
};

// Act — should not throw
var provider = new AgentSkillsProvider(new AgentFileSkillsSource(this._testRoot, s_noOpExecutor), options);

// Assert
Assert.NotNull(provider);
}

/// <summary>
/// A test skill source that counts how many times <see cref="GetSkillsAsync"/> is called.
/// </summary>
Expand Down