.NET: Fix FileAgentSkillsProvider custom SkillsInstructionPrompt silently dropping skills#4388
Merged
SergeyMenshykh merged 1 commit intomicrosoft:mainfrom Mar 2, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a bug in the .NET FileAgentSkillsProvider where supplying a custom SkillsInstructionPrompt could cause the generated skills list to be silently omitted from the final instructions presented to the LLM.
Changes:
- Preserve the original custom prompt template after validation so the
{0}placeholder remains available for later skills insertion. - Strengthen the unit test to assert that skill name and description appear in the rendered instructions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| dotnet/src/Microsoft.Agents.AI/Skills/FileAgentSkillsProvider.cs | Fixes template validation so it no longer overwrites the {0} placeholder, preventing skills from being dropped. |
| dotnet/tests/Microsoft.Agents.AI.UnitTests/AgentSkills/FileAgentSkillsProviderTests.cs | Improves coverage by asserting rendered output includes skill name/description when using a custom template. |
Comments suppressed due to low confidence (1)
dotnet/src/Microsoft.Agents.AI/Skills/FileAgentSkillsProvider.cs:183
- The validation here doesn’t actually enforce that the custom prompt contains a
{0}placeholder.string.Format("no placeholder", arg)succeeds and silently ignores the argument, which would still result in the generated skills list being dropped later instring.Format(promptTemplate, ...)—contradicting both the exception message andFileAgentSkillsProviderOptionsdocs. Consider explicitly verifying the placeholder is used (e.g., format with a unique sentinel and ensure it appears in the output, or check for an unescaped{0format item) and throw anArgumentExceptionwhen it’s missing.
_ = string.Format(optionsInstructions, string.Empty);
promptTemplate = optionsInstructions;
}
catch (FormatException ex)
{
throw new ArgumentException(
"The provided SkillsInstructionPrompt is not a valid format string. It must contain a '{0}' placeholder and escape any literal '{' or '}' by doubling them ('{{' or '}}').",
westey-m
approved these changes
Mar 2, 2026
rogerbarreto
approved these changes
Mar 2, 2026
This was referenced Mar 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix
Fixes #4344
Problem
When providing a custom
SkillsInstructionPromptviaFileAgentSkillsProviderOptions, the template validation inBuildSkillsInstructionPromptprematurely rendered the template with an empty string and assigned the result back topromptTemplate:This replaced the
{0}placeholder, so when the actual skills XML was later passed tostring.Format(promptTemplate, sb.ToString()), it was silently discarded. The LLM never saw any skills in its system instructions.Fix
The validation now discards the rendered result and preserves the original template:
Test improvement
Strengthened the
InvokingCoreAsync_CustomPromptTemplate_UsesCustomTemplateAsynctest to verify that skill name and description actually appear in the rendered output, not just the template prefix.