99 lines
3.8 KiB
C#
99 lines
3.8 KiB
C#
|
|
using Pgvector;
|
||
|
|
using TeamUp.SharedKernel.Domain;
|
||
|
|
|
||
|
|
namespace TeamUp.Modules.Skills.Domain;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// An indexed skill atom: the projection of a SKILL.md (Git is the source of truth) into a
|
||
|
|
/// queryable Postgres + pgvector row. Identified by (SkillKey, Version).
|
||
|
|
/// </summary>
|
||
|
|
internal sealed class Skill : Entity
|
||
|
|
{
|
||
|
|
public string SkillKey { get; private set; } = null!;
|
||
|
|
public string Name { get; private set; } = null!;
|
||
|
|
public string Version { get; private set; } = null!;
|
||
|
|
public string? Summary { get; private set; }
|
||
|
|
public List<string> Roles { get; private set; } = [];
|
||
|
|
public string? Inputs { get; private set; }
|
||
|
|
public string? Outputs { get; private set; }
|
||
|
|
public List<SkillAction> Actions { get; private set; } = [];
|
||
|
|
public List<string> Tools { get; private set; } = [];
|
||
|
|
public List<string> Context { get; private set; } = [];
|
||
|
|
public List<GoldenExample> GoldenTests { get; private set; } = [];
|
||
|
|
public SkillVisibility Visibility { get; private set; }
|
||
|
|
public SkillTier MinTier { get; private set; }
|
||
|
|
public SkillStatus Status { get; private set; }
|
||
|
|
public string Body { get; private set; } = null!;
|
||
|
|
public string ContentHash { get; private set; } = null!;
|
||
|
|
public string? SourceRepo { get; private set; }
|
||
|
|
public string? SourcePath { get; private set; }
|
||
|
|
public string? SourceCommit { get; private set; }
|
||
|
|
public Vector? Embedding { get; private set; }
|
||
|
|
public DateTimeOffset IndexedAtUtc { get; private set; }
|
||
|
|
public DateTimeOffset UpdatedAtUtc { get; private set; }
|
||
|
|
|
||
|
|
private Skill()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Skill Create(string skillKey, string version, DateTimeOffset nowUtc) =>
|
||
|
|
new() { SkillKey = skillKey, Version = version, IndexedAtUtc = nowUtc };
|
||
|
|
|
||
|
|
/// <summary>(Re)projects a parsed manifest + body onto this row. Used for both insert and update.</summary>
|
||
|
|
public void Index(
|
||
|
|
SkillManifest manifest,
|
||
|
|
string body,
|
||
|
|
string contentHash,
|
||
|
|
string? sourceRepo,
|
||
|
|
string? sourcePath,
|
||
|
|
string? sourceCommit,
|
||
|
|
Vector? embedding,
|
||
|
|
SkillStatus status,
|
||
|
|
DateTimeOffset nowUtc)
|
||
|
|
{
|
||
|
|
Name = string.IsNullOrWhiteSpace(manifest.Name) ? manifest.Id : manifest.Name;
|
||
|
|
Version = manifest.Version;
|
||
|
|
Summary = manifest.Summary;
|
||
|
|
Roles = manifest.Roles;
|
||
|
|
Inputs = manifest.Inputs;
|
||
|
|
Outputs = manifest.Outputs;
|
||
|
|
Actions = manifest.Actions
|
||
|
|
.Select(a => new SkillAction { Name = a.Name, Risk = ParseRisk(a.Risk), Description = a.Description })
|
||
|
|
.ToList();
|
||
|
|
Tools = manifest.Tools;
|
||
|
|
Context = manifest.Context;
|
||
|
|
GoldenTests = manifest.GoldenTests;
|
||
|
|
Visibility = ParseVisibility(manifest.Visibility);
|
||
|
|
MinTier = ParseTier(manifest.MinTier);
|
||
|
|
Status = status;
|
||
|
|
Body = body;
|
||
|
|
ContentHash = contentHash;
|
||
|
|
SourceRepo = sourceRepo;
|
||
|
|
SourcePath = sourcePath;
|
||
|
|
SourceCommit = sourceCommit;
|
||
|
|
Embedding = embedding;
|
||
|
|
UpdatedAtUtc = nowUtc;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static string Normalize(string value) => value.Trim().Replace("-", string.Empty).Replace("_", string.Empty);
|
||
|
|
|
||
|
|
private static ActionRisk ParseRisk(string value) => Normalize(value).ToLowerInvariant() switch
|
||
|
|
{
|
||
|
|
"draft" => ActionRisk.Draft,
|
||
|
|
"publish" => ActionRisk.Publish,
|
||
|
|
"destructive" => ActionRisk.Destructive,
|
||
|
|
_ => ActionRisk.Read,
|
||
|
|
};
|
||
|
|
|
||
|
|
private static SkillVisibility ParseVisibility(string value) =>
|
||
|
|
Normalize(value).ToLowerInvariant() is "privatetoorg" or "private" ? SkillVisibility.PrivateToOrg : SkillVisibility.Public;
|
||
|
|
|
||
|
|
private static SkillTier ParseTier(string value) => Normalize(value).ToLowerInvariant() switch
|
||
|
|
{
|
||
|
|
"team" => SkillTier.Team,
|
||
|
|
"scale" => SkillTier.Scale,
|
||
|
|
"enterprise" => SkillTier.Enterprise,
|
||
|
|
_ => SkillTier.Free,
|
||
|
|
};
|
||
|
|
}
|