0bcf16e77f
Reusable agent definitions authored as AGENTS.md (YAML frontmatter + a Markdown body that becomes the agent's operating guide). Mirrors the skill library, including its review hardening. - AgentProfile entity (OrgBoard): org-scoped + versioned by (OrganizationId, ProfileKey, Version), NULLS NOT DISTINCT unique index; Origin Builtin|Authored|Installed; ProfileVisibility + ProfileStatus with the Public⟹Published invariant enforced in Apply()/SetVisibility(). AGENTS.md parser (YamlDotNet). AgentProfileWriter is the single upsert path (insert-only mode for install). - Free builtins: AgentProfileSeeder seeds Aria (PO), Quill (QA), Edison (backend) on startup via a new IStartupSeeder + SeederRunner (runs after migrations). Idempotent, null-org, visible to all. - Endpoints (/api/orgboard/agent-profiles): upload, list (resolvable-winner order), get versions, publish/unpublish, fork, marketplace (per-(key,version) AlreadyInLibrary), install (insert-only → clean 409, no clobber). ConfigureAgents to author/manage; ViewBoard to browse; audited. - Persona: Agent gains Persona; ConfigureAgent stores it; AgentRunContext carries it; PromptAssembler injects it as "# Operating guide" (data, not instructions) so an applied profile shapes the run. - Client: Agent profiles page (library + marketplace tabs, upload editor, publish/unlist/fork/install), routed + in the nav. Verified: ArchitectureTests 8/8, IntegrationTests 55/55 (new AgentProfilesTests: builtins seeded, upload + validation, publish, cross-org marketplace list→install→private copy, duplicate 409, per- version flag, Member 403; persona renders as the operating guide), client build green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
37 lines
1.3 KiB
C#
37 lines
1.3 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using TeamUp.Modules.OrgBoard.Persistence;
|
|
using TeamUp.SharedKernel.Ai;
|
|
|
|
namespace TeamUp.Modules.OrgBoard.Runtime;
|
|
|
|
/// <summary>Gathers the agent config + task into an <see cref="AgentRunContext"/> for the assembler.</summary>
|
|
internal sealed class AgentRunContextProvider(OrgBoardDbContext db) : IAgentRunContextProvider
|
|
{
|
|
public async Task<AgentRunContext?> GetAsync(Guid seatId, Guid workItemId, CancellationToken cancellationToken = default)
|
|
{
|
|
var agent = await db.Agents.FirstOrDefaultAsync(a => a.SeatId == seatId, cancellationToken);
|
|
if (agent is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var item = await db.WorkItems.FirstOrDefaultAsync(w => w.Id == workItemId, cancellationToken);
|
|
if (item is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var team = await db.Teams.FirstOrDefaultAsync(t => t.Id == item.TeamId, cancellationToken);
|
|
if (team is null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return new AgentRunContext(
|
|
seatId, agent.Id, agent.Name, agent.Monogram, agent.Autonomy,
|
|
agent.ApiConfigId, agent.FallbackApiConfigId, agent.SkillKeys, agent.McpServerIds, agent.Docs, agent.Persona,
|
|
item.Id, item.Title, item.Description, item.Type.ToString(),
|
|
team.Id, team.OrganizationId);
|
|
}
|
|
}
|