Compare commits
1 Commits
chore/ms22
...
feat/ms22-
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ec1906a20 |
@@ -49,7 +49,6 @@ import { PersonalitiesModule } from "./personalities/personalities.module";
|
|||||||
import { WorkspacesModule } from "./workspaces/workspaces.module";
|
import { WorkspacesModule } from "./workspaces/workspaces.module";
|
||||||
import { AdminModule } from "./admin/admin.module";
|
import { AdminModule } from "./admin/admin.module";
|
||||||
import { AgentTemplateModule } from "./agent-template/agent-template.module";
|
import { AgentTemplateModule } from "./agent-template/agent-template.module";
|
||||||
import { UserAgentModule } from "./user-agent/user-agent.module";
|
|
||||||
import { TeamsModule } from "./teams/teams.module";
|
import { TeamsModule } from "./teams/teams.module";
|
||||||
import { ImportModule } from "./import/import.module";
|
import { ImportModule } from "./import/import.module";
|
||||||
import { ConversationArchiveModule } from "./conversation-archive/conversation-archive.module";
|
import { ConversationArchiveModule } from "./conversation-archive/conversation-archive.module";
|
||||||
@@ -132,7 +131,6 @@ import { OrchestratorModule } from "./orchestrator/orchestrator.module";
|
|||||||
WorkspacesModule,
|
WorkspacesModule,
|
||||||
AdminModule,
|
AdminModule,
|
||||||
AgentTemplateModule,
|
AgentTemplateModule,
|
||||||
UserAgentModule,
|
|
||||||
TeamsModule,
|
TeamsModule,
|
||||||
ImportModule,
|
ImportModule,
|
||||||
ConversationArchiveModule,
|
ConversationArchiveModule,
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
import { IsString, IsBoolean, IsOptional, IsArray, MinLength } from "class-validator";
|
|
||||||
|
|
||||||
export class CreateUserAgentDto {
|
|
||||||
@IsString()
|
|
||||||
@MinLength(1)
|
|
||||||
templateId?: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@MinLength(1)
|
|
||||||
name!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@MinLength(1)
|
|
||||||
displayName!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@MinLength(1)
|
|
||||||
role!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@MinLength(1)
|
|
||||||
personality!: string;
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
primaryModel?: string;
|
|
||||||
|
|
||||||
@IsArray()
|
|
||||||
@IsOptional()
|
|
||||||
fallbackModels?: string[];
|
|
||||||
|
|
||||||
@IsArray()
|
|
||||||
@IsOptional()
|
|
||||||
toolPermissions?: string[];
|
|
||||||
|
|
||||||
@IsString()
|
|
||||||
@IsOptional()
|
|
||||||
discordChannel?: string;
|
|
||||||
|
|
||||||
@IsBoolean()
|
|
||||||
@IsOptional()
|
|
||||||
isActive?: boolean;
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import { PartialType } from "@nestjs/mapped-types";
|
|
||||||
import { CreateUserAgentDto } from "./create-user-agent.dto";
|
|
||||||
|
|
||||||
export class UpdateUserAgentDto extends PartialType(CreateUserAgentDto) {}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import {
|
|
||||||
Controller,
|
|
||||||
Get,
|
|
||||||
Post,
|
|
||||||
Patch,
|
|
||||||
Delete,
|
|
||||||
Body,
|
|
||||||
Param,
|
|
||||||
UseGuards,
|
|
||||||
ParseUUIDPipe,
|
|
||||||
} from "@nestjs/common";
|
|
||||||
import { UserAgentService } from "./user-agent.service";
|
|
||||||
import { CreateUserAgentDto } from "./dto/create-user-agent.dto";
|
|
||||||
import { UpdateUserAgentDto } from "./dto/update-user-agent.dto";
|
|
||||||
import { AuthGuard } from "../auth/guards/auth.guard";
|
|
||||||
import { CurrentUser } from "../auth/decorators/current-user.decorator";
|
|
||||||
import type { AuthUser } from "@mosaic/shared";
|
|
||||||
|
|
||||||
@Controller("agents")
|
|
||||||
@UseGuards(AuthGuard)
|
|
||||||
export class UserAgentController {
|
|
||||||
constructor(private readonly userAgentService: UserAgentService) {}
|
|
||||||
|
|
||||||
@Get()
|
|
||||||
findAll(@CurrentUser() user: AuthUser) {
|
|
||||||
return this.userAgentService.findAll(user.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Get(":id")
|
|
||||||
findOne(@CurrentUser() user: AuthUser, @Param("id", ParseUUIDPipe) id: string) {
|
|
||||||
return this.userAgentService.findOne(user.id, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post()
|
|
||||||
create(@CurrentUser() user: AuthUser, @Body() dto: CreateUserAgentDto) {
|
|
||||||
return this.userAgentService.create(user.id, dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post("from-template/:templateId")
|
|
||||||
createFromTemplate(
|
|
||||||
@CurrentUser() user: AuthUser,
|
|
||||||
@Param("templateId", ParseUUIDPipe) templateId: string
|
|
||||||
) {
|
|
||||||
return this.userAgentService.createFromTemplate(user.id, templateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Patch(":id")
|
|
||||||
update(
|
|
||||||
@CurrentUser() user: AuthUser,
|
|
||||||
@Param("id", ParseUUIDPipe) id: string,
|
|
||||||
@Body() dto: UpdateUserAgentDto
|
|
||||||
) {
|
|
||||||
return this.userAgentService.update(user.id, id, dto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Delete(":id")
|
|
||||||
remove(@CurrentUser() user: AuthUser, @Param("id", ParseUUIDPipe) id: string) {
|
|
||||||
return this.userAgentService.remove(user.id, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import { Module } from "@nestjs/common";
|
|
||||||
import { UserAgentService } from "./user-agent.service";
|
|
||||||
import { UserAgentController } from "./user-agent.controller";
|
|
||||||
import { PrismaModule } from "../prisma/prisma.module";
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports: [PrismaModule],
|
|
||||||
controllers: [UserAgentController],
|
|
||||||
providers: [UserAgentService],
|
|
||||||
exports: [UserAgentService],
|
|
||||||
})
|
|
||||||
export class UserAgentModule {}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
import {
|
|
||||||
Injectable,
|
|
||||||
NotFoundException,
|
|
||||||
ConflictException,
|
|
||||||
ForbiddenException,
|
|
||||||
} from "@nestjs/common";
|
|
||||||
import { PrismaService } from "../prisma/prisma.service";
|
|
||||||
import { CreateUserAgentDto } from "./dto/create-user-agent.dto";
|
|
||||||
import { UpdateUserAgentDto } from "./dto/update-user-agent.dto";
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class UserAgentService {
|
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
|
||||||
|
|
||||||
async findAll(userId: string) {
|
|
||||||
return this.prisma.userAgent.findMany({
|
|
||||||
where: { userId },
|
|
||||||
orderBy: { createdAt: "asc" },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async findOne(userId: string, id: string) {
|
|
||||||
const agent = await this.prisma.userAgent.findUnique({ where: { id } });
|
|
||||||
if (!agent) throw new NotFoundException(`UserAgent ${id} not found`);
|
|
||||||
if (agent.userId !== userId) throw new ForbiddenException("Access denied to this agent");
|
|
||||||
return agent;
|
|
||||||
}
|
|
||||||
|
|
||||||
async findByName(userId: string, name: string) {
|
|
||||||
const agent = await this.prisma.userAgent.findUnique({
|
|
||||||
where: { userId_name: { userId, name } },
|
|
||||||
});
|
|
||||||
if (!agent) throw new NotFoundException(`UserAgent "${name}" not found for user`);
|
|
||||||
return agent;
|
|
||||||
}
|
|
||||||
|
|
||||||
async create(userId: string, dto: CreateUserAgentDto) {
|
|
||||||
// Check for unique name within user scope
|
|
||||||
const existing = await this.prisma.userAgent.findUnique({
|
|
||||||
where: { userId_name: { userId, name: dto.name } },
|
|
||||||
});
|
|
||||||
if (existing)
|
|
||||||
throw new ConflictException(`UserAgent "${dto.name}" already exists for this user`);
|
|
||||||
|
|
||||||
// If templateId provided, verify it exists
|
|
||||||
if (dto.templateId) {
|
|
||||||
const template = await this.prisma.agentTemplate.findUnique({
|
|
||||||
where: { id: dto.templateId },
|
|
||||||
});
|
|
||||||
if (!template) throw new NotFoundException(`AgentTemplate ${dto.templateId} not found`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.prisma.userAgent.create({
|
|
||||||
data: {
|
|
||||||
userId,
|
|
||||||
templateId: dto.templateId ?? null,
|
|
||||||
name: dto.name,
|
|
||||||
displayName: dto.displayName,
|
|
||||||
role: dto.role,
|
|
||||||
personality: dto.personality,
|
|
||||||
primaryModel: dto.primaryModel ?? null,
|
|
||||||
fallbackModels: dto.fallbackModels ?? ([] as string[]),
|
|
||||||
toolPermissions: dto.toolPermissions ?? ([] as string[]),
|
|
||||||
discordChannel: dto.discordChannel ?? null,
|
|
||||||
isActive: dto.isActive ?? true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async createFromTemplate(userId: string, templateId: string) {
|
|
||||||
const template = await this.prisma.agentTemplate.findUnique({
|
|
||||||
where: { id: templateId },
|
|
||||||
});
|
|
||||||
if (!template) throw new NotFoundException(`AgentTemplate ${templateId} not found`);
|
|
||||||
|
|
||||||
// Check for unique name within user scope
|
|
||||||
const existing = await this.prisma.userAgent.findUnique({
|
|
||||||
where: { userId_name: { userId, name: template.name } },
|
|
||||||
});
|
|
||||||
if (existing)
|
|
||||||
throw new ConflictException(`UserAgent "${template.name}" already exists for this user`);
|
|
||||||
|
|
||||||
return this.prisma.userAgent.create({
|
|
||||||
data: {
|
|
||||||
userId,
|
|
||||||
templateId: template.id,
|
|
||||||
name: template.name,
|
|
||||||
displayName: template.displayName,
|
|
||||||
role: template.role,
|
|
||||||
personality: template.personality,
|
|
||||||
primaryModel: template.primaryModel,
|
|
||||||
fallbackModels: template.fallbackModels as string[],
|
|
||||||
toolPermissions: template.toolPermissions as string[],
|
|
||||||
discordChannel: template.discordChannel,
|
|
||||||
isActive: template.isActive,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async update(userId: string, id: string, dto: UpdateUserAgentDto) {
|
|
||||||
const agent = await this.findOne(userId, id);
|
|
||||||
|
|
||||||
// If name is being changed, check for uniqueness
|
|
||||||
if (dto.name && dto.name !== agent.name) {
|
|
||||||
const existing = await this.prisma.userAgent.findUnique({
|
|
||||||
where: { userId_name: { userId, name: dto.name } },
|
|
||||||
});
|
|
||||||
if (existing)
|
|
||||||
throw new ConflictException(`UserAgent "${dto.name}" already exists for this user`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.prisma.userAgent.update({
|
|
||||||
where: { id },
|
|
||||||
data: dto,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async remove(userId: string, id: string) {
|
|
||||||
await this.findOne(userId, id);
|
|
||||||
return this.prisma.userAgent.delete({ where: { id } });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
| --- | ------------- | ------------- | ---------- | -------------- | --------------------- |
|
| --- | ------------- | ------------- | ---------- | -------------- | --------------------- |
|
||||||
| 1 | schema-seed | Schema+Seed | ✅ done | P2-001, P2-002 | PRs #675, #677 merged |
|
| 1 | schema-seed | Schema+Seed | ✅ done | P2-001, P2-002 | PRs #675, #677 merged |
|
||||||
| 2 | admin-crud | Admin CRUD | ✅ done | P2-003 | PR #678 merged |
|
| 2 | admin-crud | Admin CRUD | ✅ done | P2-003 | PR #678 merged |
|
||||||
| 3 | user-crud | User CRUD | ✅ done | P2-004 | PR #682 merged |
|
| 3 | user-crud | User CRUD | 🔄 next | P2-004 | Depends on M2 |
|
||||||
| 4 | agent-routing | Agent Routing | ⬜ pending | P2-005, P2-006 | Depends on M3 |
|
| 4 | agent-routing | Agent Routing | ⬜ pending | P2-005, P2-006 | Depends on M3 |
|
||||||
| 5 | discord-ui | Discord+UI | ⬜ pending | P2-007, P2-008 | Depends on M4 |
|
| 5 | discord-ui | Discord+UI | ⬜ pending | P2-007, P2-008 | Depends on M4 |
|
||||||
| 6 | verification | Verification | ⬜ pending | P2-009, P2-010 | Final gate |
|
| 6 | verification | Verification | ⬜ pending | P2-009, P2-010 | Final gate |
|
||||||
@@ -42,7 +42,7 @@ See `docs/TASKS.md` — MS22 Phase 2 section for full task details.
|
|||||||
| P2-001 Schema | ✅ done | #675 | AgentTemplate + UserAgent |
|
| P2-001 Schema | ✅ done | #675 | AgentTemplate + UserAgent |
|
||||||
| P2-002 Seed | ✅ done | #677 | jarvis/builder/medic templates |
|
| P2-002 Seed | ✅ done | #677 | jarvis/builder/medic templates |
|
||||||
| P2-003 Admin CRUD | ✅ done | #678 | /admin/agent-templates |
|
| P2-003 Admin CRUD | ✅ done | #678 | /admin/agent-templates |
|
||||||
| P2-004 User CRUD | ✅ done | #682 | /api/agents |
|
| P2-004 User CRUD | ⬜ not-started | — | |
|
||||||
| P2-005 Status endpoints | ⬜ not-started | — | |
|
| P2-005 Status endpoints | ⬜ not-started | — | |
|
||||||
| P2-006 Chat routing | ⬜ not-started | — | |
|
| P2-006 Chat routing | ⬜ not-started | — | |
|
||||||
| P2-007 Discord routing | ⬜ not-started | — | |
|
| P2-007 Discord routing | ⬜ not-started | — | |
|
||||||
@@ -54,15 +54,14 @@ See `docs/TASKS.md` — MS22 Phase 2 section for full task details.
|
|||||||
|
|
||||||
| Phase | Est | Used |
|
| Phase | Est | Used |
|
||||||
| ----------------- | -------- | -------------------- |
|
| ----------------- | -------- | -------------------- |
|
||||||
| Schema+Seed+CRUD | 30K | ~15K (done directly) |
|
| Schema+Seed+CRUD | 30K | ~10K (done directly) |
|
||||||
| User CRUD+Routing | 40K | ~25K |
|
| User CRUD+Routing | 40K | — |
|
||||||
| Discord+UI | 30K | — |
|
| Discord+UI | 30K | — |
|
||||||
| Verification | 10K | — |
|
| Verification | 10K | — |
|
||||||
| **Total** | **110K** | **~40K** |
|
| **Total** | **110K** | **~10K** |
|
||||||
|
|
||||||
## Session Log
|
## Session Log
|
||||||
|
|
||||||
| Date | Work Done |
|
| Date | Work Done |
|
||||||
| ---------- | --------------------------------------------------------------------------------------------------------- |
|
| ---------- | ------------------------------------------------------------------ |
|
||||||
| 2026-03-04 | Session 2: Fixed CI security audit, merged PRs #681, #678, #682. Milestones 1-3 complete (4/6 remaining). |
|
| 2026-03-04 | P2-001..003 shipped; CI fix; postgres rebuilt; mission initialized |
|
||||||
| 2026-03-04 | P2-001..003 shipped; CI fix; postgres rebuilt; mission initialized |
|
|
||||||
|
|||||||
@@ -97,9 +97,9 @@ PRD: `docs/PRD-MS22-P2-AGENT-FLEET.md`
|
|||||||
| Task ID | Status | Phase | Description | Issue | Scope | Branch | Depends On | Blocks | Assigned Worker | Started | Completed | Est Tokens | Act Tokens | Notes |
|
| Task ID | Status | Phase | Description | Issue | Scope | Branch | Depends On | Blocks | Assigned Worker | Started | Completed | Est Tokens | Act Tokens | Notes |
|
||||||
| ----------- | ----------- | -------- | -------------------------------------------- | -------- | ----- | --------------------------- | ------------- | ------------- | --------------- | ---------- | ---------- | ---------- | ---------- | -------------- |
|
| ----------- | ----------- | -------- | -------------------------------------------- | -------- | ----- | --------------------------- | ------------- | ------------- | --------------- | ---------- | ---------- | ---------- | ---------- | -------------- |
|
||||||
| MS22-P2-001 | done | p2-fleet | Prisma schema: AgentTemplate, UserAgent | TASKS:P2 | api | feat/ms22-p2-agent-schema | MS22-P1a | P2-002,P2-003 | orchestrator | 2026-03-04 | 2026-03-04 | 10K | 3K | PR #675 merged |
|
| MS22-P2-001 | done | p2-fleet | Prisma schema: AgentTemplate, UserAgent | TASKS:P2 | api | feat/ms22-p2-agent-schema | MS22-P1a | P2-002,P2-003 | orchestrator | 2026-03-04 | 2026-03-04 | 10K | 3K | PR #675 merged |
|
||||||
| MS22-P2-002 | done | p2-fleet | Seed default agents (jarvis, builder, medic) | TASKS:P2 | api | feat/ms22-p2-agent-seed | P2-001 | P2-004 | orchestrator | 2026-03-04 | 2026-03-04 | 5K | 2K | PR #677 merged |
|
| MS22-P2-002 | not-started | p2-fleet | Seed default agents (jarvis, builder, medic) | TASKS:P2 | api | feat/ms22-p2-agent-seed | P2-001 | P2-004 | — | — | — | 5K | — | |
|
||||||
| MS22-P2-003 | done | p2-fleet | Agent template CRUD endpoints (admin) | TASKS:P2 | api | feat/ms22-p2-agent-crud | P2-001 | P2-005 | orchestrator | 2026-03-04 | 2026-03-04 | 15K | 5K | PR #678 merged |
|
| MS22-P2-003 | not-started | p2-fleet | Agent template CRUD endpoints (admin) | TASKS:P2 | api | feat/ms22-p2-agent-api | P2-001 | P2-005 | — | — | — | 15K | — | |
|
||||||
| MS22-P2-004 | done | p2-fleet | User agent CRUD endpoints | TASKS:P2 | api | feat/ms22-p2-user-agents | P2-002,P2-003 | P2-006 | orchestrator | 2026-03-04 | 2026-03-04 | 15K | 8K | PR #682 merged |
|
| MS22-P2-004 | not-started | p2-fleet | User agent CRUD endpoints | TASKS:P2 | api | feat/ms22-p2-agent-api | P2-002,P2-003 | P2-006 | — | — | — | 15K | — | |
|
||||||
| MS22-P2-005 | not-started | p2-fleet | Agent status endpoints | TASKS:P2 | api | feat/ms22-p2-agent-api | P2-003 | P2-008 | — | — | — | 10K | — | |
|
| MS22-P2-005 | not-started | p2-fleet | Agent status endpoints | TASKS:P2 | api | feat/ms22-p2-agent-api | P2-003 | P2-008 | — | — | — | 10K | — | |
|
||||||
| MS22-P2-006 | not-started | p2-fleet | Agent chat routing (select agent by name) | TASKS:P2 | api | feat/ms22-p2-agent-routing | P2-004 | P2-007 | — | — | — | 15K | — | |
|
| MS22-P2-006 | not-started | p2-fleet | Agent chat routing (select agent by name) | TASKS:P2 | api | feat/ms22-p2-agent-routing | P2-004 | P2-007 | — | — | — | 15K | — | |
|
||||||
| MS22-P2-007 | not-started | p2-fleet | Discord channel → agent routing | TASKS:P2 | api | feat/ms22-p2-discord-router | P2-006 | P2-009 | — | — | — | 15K | — | |
|
| MS22-P2-007 | not-started | p2-fleet | Discord channel → agent routing | TASKS:P2 | api | feat/ms22-p2-discord-router | P2-006 | P2-009 | — | — | — | 15K | — | |
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
# Mission Scratchpad — MS22-P2 Named Agent Fleet
|
|
||||||
|
|
||||||
> Append-only log. NEVER delete entries. NEVER overwrite sections.
|
|
||||||
> This is the orchestrator's working memory across sessions.
|
|
||||||
|
|
||||||
## Original Mission Prompt
|
|
||||||
|
|
||||||
```
|
|
||||||
(Paste the mission prompt here on first session)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Planning Decisions
|
|
||||||
|
|
||||||
## Session Log
|
|
||||||
|
|
||||||
| Session | Date | Milestone | Tasks Done | Outcome |
|
|
||||||
| ------- | ---------- | --------- | ---------------------- | ------------------------------------------------------------------------------ |
|
|
||||||
| 2 | 2026-03-04 | M1+M2+M3 | P2-004 done | Fixed CI security audit, merged PRs #681, #678, #682. Milestones 1-3 complete. |
|
|
||||||
| 1 | 2026-03-04 | M1+M2 | P2-001, P2-002, P2-003 | Schema, seed, and Admin CRUD complete |
|
|
||||||
|
|
||||||
## Open Questions
|
|
||||||
|
|
||||||
## Corrections
|
|
||||||
Reference in New Issue
Block a user