# DailyBriefGenerationPipeline — A2A Spec

**Product:** MindLyst  
**Trigger:** Cron (`0 7 * * *` per-user timezone), or on-demand via MCP tool `mindlyst.brief.generate(userId)`  
**Output:** `DailyBriefDoc` in `daily_briefs` Cosmos container + push notification

---

## Agent roster

| Step | Agent                  | Input                                   | Output                                                                      |
| ---- | ---------------------- | --------------------------------------- | --------------------------------------------------------------------------- |
| 1    | `MemoryCollectorAgent` | `userId`, `brainIds[]`, lookback window | Top N memory items per brain ranked by `urgencyScore`                       |
| 2    | `SummaryAgent`         | Memory items per brain                  | Per-brain summary text (calls `extraction.extract(text, 'memory-insight')`) |
| 3    | `BriefComposerAgent`   | Per-brain summaries + user preferences  | `DailyBriefDoc` draft                                                       |
| 4    | `DeliveryAgent`        | `DailyBriefDoc` + `userId`              | Stored doc + push notification fired                                        |

---

## Agent contracts

### MemoryCollectorAgent

```typescript
// Tool: mindlyst.memory.listByBrain
// Endpoint: GET /memory-items?productId=mindlyst&brainId=<id>&filter=forgotten&limit=20
// Returns: { items: MemoryItemDoc[], limit, offset }
input: {
  userId: string;
  brainIds: string[];
  lookbackHours?: number; // default 24
}
output: {
  byBrain: Record<string, MemoryItemDoc[]>;
  totalItems: number;
}
```

### SummaryAgent

```typescript
// Tool: extraction.extract
// Endpoint: POST extraction-service /api/extract { text, taskId: 'memory-insight' }
input: {
  brainId: string;
  items: MemoryItemDoc[];
}
output: {
  brainId: string;
  summary: string;
  highlights: string[]; // top entities/patterns
}
```

### BriefComposerAgent

```typescript
// Pure in-process transformation — no external calls
input: {
  userId: string;
  brainSummaries: Array<{ brainId: string; summary: string; highlights: string[] }>;
  date: string; // ISO date
}
output: DailyBriefDoc; // ready to upsert
```

### DeliveryAgent

```typescript
// Tool: mindlyst.brief.store → POST /daily-briefs
// Tool: platform.push.fire → POST platform-service /push-triggers
input: {
  brief: DailyBriefDoc;
  userId: string;
}
output: {
  stored: boolean;
  notified: boolean;
  briefId: string;
}
```

---

## Data model

```typescript
interface DailyBriefDoc {
  id: string;
  userId: string;
  productId: 'mindlyst';
  date: string; // YYYY-MM-DD
  greeting: string;
  brainSummaries: BrainSummary[];
  priorityItems: MemoryItemRef[];
  totalMemoriesConsidered: number;
  generatedAt: string;
  deliveredAt: string | null;
}
```

---

## Error handling

- If `extraction-service` is unavailable, `SummaryAgent` falls back to a simple top-3 item list (no extraction).
- If any brain has 0 items, it is omitted from the brief.
- If `DeliveryAgent` fails to push, it retries once; the brief is still stored.
- Idempotent: re-running for the same `(userId, date)` upserts the existing doc.

---

## MCP tool surface

```typescript
mindlyst.brief.generate(userId: string, date?: string): DailyBriefDoc
mindlyst.brief.get(userId: string, date: string): DailyBriefDoc | null
mindlyst.brief.list(userId: string, limit?: number): DailyBriefDoc[]
```

---

## Implementation checklist

- [ ] `MemoryCollectorAgent` — thin wrapper over `GET /memory-items` (multi-brain fan-out)
- [ ] `SummaryAgent` — calls extraction-service `memory-insight` task
- [ ] `BriefComposerAgent` — template assembly + LLM call for greeting
- [ ] `DeliveryAgent` — upsert to `daily_briefs` + fire push trigger
- [ ] Cron registration in `backend/src/server.ts` (Fastify cron plugin or external scheduler)
- [ ] MCP tool registrations in `backend/src/modules/daily-briefs/routes.ts`
