-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathSkillsTests.cs
More file actions
119 lines (92 loc) · 4.24 KB
/
Copy pathSkillsTests.cs
File metadata and controls
119 lines (92 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
using Xunit;
using Xunit.Abstractions;
namespace GitHub.Copilot.SDK.Test;
public class SkillsTests : E2ETestBase
{
private const string SkillMarker = "PINEAPPLE_COCONUT_42";
private readonly string _workDir;
public SkillsTests(E2ETestFixture fixture, ITestOutputHelper output) : base(fixture, "skills", output)
{
_workDir = fixture.Ctx.WorkDir;
var skillsDir = Path.Join(_workDir, ".test_skills");
if (Directory.Exists(skillsDir))
{
Directory.Delete(skillsDir, recursive: true);
}
}
private string CreateSkillDir()
{
var skillsDir = Path.Join(_workDir, ".test_skills");
Directory.CreateDirectory(skillsDir);
// Create a skill subdirectory with SKILL.md
var skillSubdir = Path.Join(skillsDir, "test-skill");
Directory.CreateDirectory(skillSubdir);
// Create a skill that instructs the model to include a specific marker in responses
var skillContent = $@"---
name: test-skill
description: A test skill that adds a marker to responses
---
# Test Skill Instructions
IMPORTANT: You MUST include the exact text ""{SkillMarker}"" somewhere in EVERY response you give. This is a mandatory requirement. Include it naturally in your response.
".ReplaceLineEndings("\n");
File.WriteAllText(Path.Join(skillSubdir, "SKILL.md"), skillContent);
return skillsDir;
}
[Fact]
public async Task Should_Load_And_Apply_Skill_From_SkillDirectories()
{
var skillsDir = CreateSkillDir();
var session = await CreateSessionAsync(new SessionConfig
{
SkillDirectories = [skillsDir]
});
Assert.Matches(@"^[a-f0-9-]+$", session.SessionId);
// The skill instructs the model to include a marker - verify it appears
var message = await session.SendAndWaitAsync(new MessageOptions { Prompt = "Say hello briefly using the test skill." });
Assert.NotNull(message);
Assert.Contains(SkillMarker, message!.Data.Content);
await session.DisposeAsync();
}
[Fact]
public async Task Should_Not_Apply_Skill_When_Disabled_Via_DisabledSkills()
{
var skillsDir = CreateSkillDir();
var session = await CreateSessionAsync(new SessionConfig
{
SkillDirectories = [skillsDir],
DisabledSkills = ["test-skill"]
});
Assert.Matches(@"^[a-f0-9-]+$", session.SessionId);
// The skill is disabled, so the marker should NOT appear
var message = await session.SendAndWaitAsync(new MessageOptions { Prompt = "Say hello briefly using the test skill." });
Assert.NotNull(message);
Assert.DoesNotContain(SkillMarker, message!.Data.Content);
await session.DisposeAsync();
}
[Fact(Skip = "See the big comment around the equivalent test in the Node SDK. Skipped because the feature doesn't work correctly yet.")]
public async Task Should_Apply_Skill_On_Session_Resume_With_SkillDirectories()
{
var skillsDir = CreateSkillDir();
// Create a session without skills first
var session1 = await CreateSessionAsync();
var sessionId = session1.SessionId;
// First message without skill - marker should not appear
var message1 = await session1.SendAndWaitAsync(new MessageOptions { Prompt = "Say hi." });
Assert.NotNull(message1);
Assert.DoesNotContain(SkillMarker, message1!.Data.Content);
// Resume with skillDirectories - skill should now be active
var session2 = await ResumeSessionAsync(sessionId, new ResumeSessionConfig
{
SkillDirectories = [skillsDir]
});
Assert.Equal(sessionId, session2.SessionId);
// Now the skill should be applied
var message2 = await session2.SendAndWaitAsync(new MessageOptions { Prompt = "Say hello again using the test skill." });
Assert.NotNull(message2);
Assert.Contains(SkillMarker, message2!.Data.Content);
await session2.DisposeAsync();
}
}