-
-
Notifications
You must be signed in to change notification settings - Fork 617
Implement agent skills #1304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Implement agent skills #1304
Changes from all commits
d3b10dc
f3e97c9
6826964
4040e4f
30b9e2e
7fd7455
3e29c73
2e7fa72
8e20bd7
c69c90f
8de5733
bb52816
0767ca5
605f4d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "appHostPath": "..\\src\\BotSharp.AppHost\\BotSharp.AppHost.csproj" | ||
| } | ||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -161,6 +161,11 @@ public class Agent | |
| [JsonIgnore] | ||
| public List<string> SecondaryInstructions { get; set; } = []; | ||
|
|
||
| /// <summary> | ||
| /// Agent skills, which is a collection of instructions, functions, and other resources for specific domains or tasks. | ||
| /// </summary> | ||
| public List<AgentSkill> Skills { get; set; } = new(); | ||
|
|
||
| public override string ToString() | ||
| => $"{Name} {Id}"; | ||
|
|
||
|
|
@@ -193,6 +198,7 @@ public static Agent Clone(Agent agent) | |
| Rules = agent.Rules, | ||
| LlmConfig = agent.LlmConfig, | ||
| KnowledgeBases = agent.KnowledgeBases, | ||
| Skills = agent.Skills, | ||
| CreatedDateTime = agent.CreatedDateTime, | ||
| UpdatedDateTime = agent.UpdatedDateTime, | ||
| }; | ||
|
|
@@ -346,4 +352,10 @@ public Agent SetMcpTools(List<McpTool>? mcps) | |
| McpTools = mcps ?? []; | ||
| return this; | ||
| } | ||
|
|
||
| public Agent SetSkills(List<AgentSkill>? skills) | ||
| { | ||
| Skills = skills ?? []; | ||
| return this; | ||
|
Comment on lines
+356
to
+359
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. setskills assigns shared list Agent.SetSkills assigns the caller-provided list directly to Skills, allowing the caller to mutate agent state after assignment. This violates the defensive-copy requirement for caller-provided collections. Agent Prompt
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| namespace BotSharp.Abstraction.Agents.Models; | ||
|
|
||
| public class AgentSkill | ||
| { | ||
| /// <summary> | ||
| /// Name of the Skill | ||
| /// </summary> | ||
| [JsonPropertyName("name")] | ||
| public required string Name { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Description of the Skill | ||
| /// </summary> | ||
| [JsonPropertyName("description")] | ||
| public required string Description { get; set; } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,6 +72,7 @@ public class AgentCreationModel | |
| public List<AgentKnowledgeBase> KnowledgeBases { get; set; } = new(); | ||
| public List<AgentRule> Rules { get; set; } = new(); | ||
| public AgentLlmConfig? LlmConfig { get; set; } | ||
| public List<AgentSkill> Skills { get; set; } | ||
|
|
||
|
Comment on lines
73
to
76
|
||
| public Agent ToAgent() | ||
| { | ||
|
|
@@ -100,6 +101,7 @@ public Agent ToAgent() | |
| KnowledgeBases = KnowledgeBases, | ||
| Rules = Rules, | ||
| RoutingRules = RoutingRules?.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?.ToList() ?? [], | ||
| Skills = Skills ?? new List<AgentSkill>(), | ||
| }; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| using BotSharp.Abstraction.Agents; | ||
| using BotSharp.Abstraction.Functions; | ||
| using BotSharp.Abstraction.Settings; | ||
| using BotSharp.Plugin.AgentSkills.Functions; | ||
| using BotSharp.Plugin.AgentSkills.Services; | ||
| using BotSharp.Plugin.AgentSkills.Skills; | ||
| using Microsoft.Extensions.AI; | ||
| using Microsoft.Extensions.Configuration; | ||
| using Microsoft.Extensions.Logging; | ||
|
|
||
| namespace BotSharp.Plugin.AgentSkills; | ||
|
|
||
| /// <summary> | ||
| /// Agent Skills plugin for BotSharp. | ||
| /// Enables AI agents to leverage reusable skills following the Agent Skills specification (https://agentskills.io). | ||
| /// Implements requirements: FR-1.1, FR-3.1, FR-4.1 | ||
| /// </summary> | ||
| public class AgentSkillsPlugin : IBotSharpPlugin | ||
| { | ||
| public string Id => "a5b3e8c1-7d2f-4a9e-b6c4-8f5d1e2a3b4c"; | ||
| public string Name => "Agent Skills"; | ||
| public string Description => "Enables AI agents to leverage reusable skills following the Agent Skills specification (https://agentskills.io)."; | ||
| public string IconUrl => "https://raw.githubusercontent.com/SciSharp/BotSharp/master/docs/static/logos/BotSharp.png"; | ||
| public string[] AgentIds => []; | ||
|
|
||
| /// <summary> | ||
| /// Register dependency injection services. | ||
| /// Implements requirements: FR-1.1, FR-3.1, FR-4.1, FR-6.1, NFR-4.1 | ||
| /// </summary> | ||
| public void RegisterDI(IServiceCollection services, IConfiguration config) | ||
| { | ||
| // FR-6.1: Register AgentSkillsSettings configuration | ||
| // Use ISettingService to bind configuration from appsettings.json | ||
| services.AddScoped(provider => | ||
| { | ||
| var settingService = provider.GetRequiredService<ISettingService>(); | ||
| return settingService.Bind<AgentSkillsSettings>("AgentSkills"); | ||
| }); | ||
|
|
||
| // FR-1.1: Register AgentSkillsFactory as singleton | ||
| // Singleton pattern avoids creating multiple factory instances | ||
| services.AddSingleton<AgentSkillsFactory>(); | ||
|
|
||
| // FR-1.1, NFR-4.1: Register ISkillService and SkillService as scoped | ||
| services.AddScoped<ISkillService, SkillService>(); | ||
|
|
||
| services.AddScoped<IFunctionCallback, GetInstructionsFn>(); | ||
| services.AddScoped<IFunctionCallback, GetSkillBynameFn>(); | ||
| services.AddScoped<IFunctionCallback, GetSkillFileContentFn>(); | ||
|
|
||
| // FR-2.1: Register AgentSkillsInstructionHook for instruction injection | ||
| services.AddScoped<IAgentHook, AgentSkillsInstructionHook>(); | ||
|
|
||
| // FR-3.1: Register AgentSkillsFunctionHook for function registration | ||
| services.AddScoped<IAgentHook, AgentSkillsFunctionHook>(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>$(TargetFramework)</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <LangVersion>$(LangVersion)</LangVersion> | ||
| <VersionPrefix>$(BotSharpVersion)</VersionPrefix> | ||
| <GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild> | ||
| <GenerateDocumentationFile>$(GenerateDocumentationFile)</GenerateDocumentationFile> | ||
| <OutputPath>$(SolutionDir)packages</OutputPath> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <Content Include="data\agents\471ca181-375f-b16f-7134-5f868ecd31c6\agent.json"> | ||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
| </Content> | ||
| <Content Include="data\agents\471ca181-375f-b16f-7134-5f868ecd31c6\instructions\instruction.liquid"> | ||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
| </Content> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="YamlDotNet" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\Infrastructure\BotSharp.Core\BotSharp.Core.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR description says the change only adds
.aspire/settings.json, but this PR also introduces a large AgentSkills plugin implementation, new test projects/assets, and storage model changes. Update the PR description to accurately reflect the scope, or split into separate PRs to keep reviews manageable.