diff --git a/docs/MCP+A2A/DOMAIN_PRODUCTS.md b/docs/MCP+A2A/DOMAIN_PRODUCTS.md index 31d62b56..47cbbd3b 100644 --- a/docs/MCP+A2A/DOMAIN_PRODUCTS.md +++ b/docs/MCP+A2A/DOMAIN_PRODUCTS.md @@ -69,7 +69,7 @@ chronomind.syncStatus(userId) ← returns offline queue depth + la ### Highest-ROI first - [x] Wire `@bytelyst/diagnostics-client` (`web/src/app/providers.tsx` + `web/src/lib/diagnostics.ts`) — [cb79c9b](https://github.com/saravanakumardb1/learning_ai_clock/commit/cb79c9b) -- [ ] Create `nl-timer-parse` extraction task (moves NL parsing to server-side, enables eval loop) +- [x] `nl-timer-parse` extraction task (`id: 'timer-parse'`) — _already seeded in extraction-service `seed.ts`_ - [x] `chronomind.syncStatus` endpoint in `backend/src/modules/timers/routes.ts` — [4a3ac76](https://github.com/saravanakumardb1/learning_ai_clock/commit/4a3ac76) --- @@ -157,7 +157,7 @@ peakpulse.weather.getSnapshot(sessionId) ← WeatherSnapshotDoc for a ses ### Highest-ROI first -- [ ] Wire `@bytelyst/diagnostics-client` into iOS `PeakPulseApp.swift` (via Platform/ wrapper) — _pending: iOS Platform/ Swift wrapper_ +- [x] Wire `ByteLystDiagnostics` into iOS `PeakPulseApp.swift` (`DiagnosticsService.swift`) — [7d4b86f](https://github.com/saravanakumardb1/learning_ai_peakpulse/commit/7d4b86f) - [x] `peakpulse.sessions.export` endpoint (`GET /peak/sessions/:id/export`) — [bfeb465](https://github.com/saravanakumardb1/learning_ai_peakpulse/commit/bfeb465) - [ ] SyncDiagnosticsAgent spec @@ -222,7 +222,7 @@ This product's own coaching "crew" maps naturally to A2A: - [x] Wire `@bytelyst/diagnostics-client` (`web/src/app/layout.tsx` + `web/src/lib/diagnostics.ts`) — [5bc1fcc](https://github.com/saravanakumardb1/learning_ai_jarvis_jr/commit/5bc1fcc) - [x] `jarvis.memory.prune` endpoint (`POST /jarvis/agents/:agentId/memory/prune`) — _already existed in codebase_ -- [ ] MarketplaceCertificationPipeline A2A spec +- [x] MarketplaceCertificationPipeline A2A spec — [docs/MCP+A2A/agents/MarketplaceCertificationPipeline.md](agents/MarketplaceCertificationPipeline.md) --- @@ -273,7 +273,7 @@ mindlyst.extractions.run(taskId, text) ← direct extraction (all 3 - [x] Wire `@bytelyst/diagnostics-client` (`mindlyst-native/web/src/app/providers.tsx` + `src/lib/diagnostics.ts`) — [a90bff2](https://github.com/saravanakumardb1/learning_multimodal_memory_agents/commit/a90bff2) - [x] `mindlyst.memory.retriage` endpoint (`POST /memory-items/:id/retriage`) — [ae5c755](https://github.com/saravanakumardb1/learning_multimodal_memory_agents/commit/ae5c755) -- [ ] DailyBriefGenerationPipeline A2A spec +- [x] DailyBriefGenerationPipeline A2A spec — [docs/MCP+A2A/agents/DailyBriefGenerationPipeline.md](agents/DailyBriefGenerationPipeline.md) --- diff --git a/docs/MCP+A2A/agents/DailyBriefGenerationPipeline.md b/docs/MCP+A2A/agents/DailyBriefGenerationPipeline.md new file mode 100644 index 00000000..cf76627d --- /dev/null +++ b/docs/MCP+A2A/agents/DailyBriefGenerationPipeline.md @@ -0,0 +1,130 @@ +# 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=&filter=forgotten&limit=20 +// Returns: { items: MemoryItemDoc[], limit, offset } +input: { + userId: string; + brainIds: string[]; + lookbackHours?: number; // default 24 +} +output: { + byBrain: Record; + 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` diff --git a/docs/MCP+A2A/agents/MarketplaceCertificationPipeline.md b/docs/MCP+A2A/agents/MarketplaceCertificationPipeline.md new file mode 100644 index 00000000..65dc3185 --- /dev/null +++ b/docs/MCP+A2A/agents/MarketplaceCertificationPipeline.md @@ -0,0 +1,148 @@ +# MarketplaceCertificationPipeline — A2A Spec + +**Product:** JarvisJr +**Trigger:** `POST /marketplace/listings/:id/submit-for-review` (author action) +**Output:** Listing status updated to `verified` or `rejected` in `marketplace_listings` Cosmos container + +--- + +## Agent roster + +| Step | Agent | Input | Output | +| ---- | ---------------------------- | ------------------------------ | ------------------------------------------------------ | +| 1 | `SubmissionIngestionAgent` | Listing doc + `listingId` | Validated field set or validation errors | +| 2 | `ContentSafetyAgent` | `systemPrompt` + `description` | Safety verdict (`pass` / `flag` / `reject`) | +| 3 | `QualityEvalAgent` | Agent config + sample phrases | Quality score (0–1) + transcript | +| 4 | `CertificationDecisionAgent` | Verdicts from agents 1–3 | Final decision, `isVerified` flag, author notification | + +--- + +## Agent contracts + +### SubmissionIngestionAgent + +```typescript +// Tool: jarvisjr.marketplace.getListing +// Endpoint: GET /marketplace/listings/:id +input: { listingId: string; submitterId: string } +output: { + valid: boolean; + errors: string[]; // missing fields + listing: MarketplaceListingDoc; +} +// Required fields: name, systemPrompt, coachingFramework, category, tags, voiceId +// Rejected immediately if any required field is blank +``` + +### ContentSafetyAgent + +```typescript +// Tool: extraction.extract { taskId: 'triage' } +// Checks systemPrompt + description against policy classes +input: { + listingId: string; + text: string; // systemPrompt + "\n\n" + description +} +output: { + verdict: 'pass' | 'flag' | 'reject'; + reasons: string[]; + confidenceScore: number; +} +// 'reject': contains prohibited content → pipeline halts +// 'flag': borderline → escalates to human review queue +// 'pass': proceed to quality eval +``` + +### QualityEvalAgent + +```typescript +// Tool: jarvisjr.sessions.createEval +// Runs a synthetic 3-turn session against the agent config +input: { + listingId: string; + agentConfig: AgentConfig; + evalPhrases: string[]; // 3 sample user prompts +} +output: { + score: number; // 0–1; threshold: 0.6 to pass + transcript: string; + coherenceIssues: string[]; +} +// Calls backend POST /jarvis/sessions/eval (internal, no auth required) +``` + +### CertificationDecisionAgent + +```typescript +// Tool: jarvisjr.marketplace.updateListing +// Endpoint: PUT /marketplace/listings/:id +// Tool: platform.notifications.send (push to listing author) +input: { + listingId: string; + submitterId: string; + ingestionResult: SubmissionIngestionResult; + safetyResult: ContentSafetyResult; + qualityResult: QualityEvalResult; +} +output: { + decision: 'approved' | 'rejected' | 'pending_human_review'; + isVerified: boolean; + rejectionReasons?: string[]; + notified: boolean; +} +// Approval: ingestionValid && safetyVerdict === 'pass' && qualityScore >= 0.6 +// Human review: safetyVerdict === 'flag' +// Rejection: ingestionInvalid || safetyVerdict === 'reject' || qualityScore < 0.6 +``` + +--- + +## Data model changes + +```typescript +// Additions to MarketplaceListingDoc +interface MarketplaceListingDoc { + // existing fields … + certificationStatus: + | 'draft' + | 'pending_review' + | 'approved' + | 'rejected' + | 'pending_human_review'; + certificationReviewedAt: string | null; + certificationReasons: string[]; + certificationQualityScore: number | null; + certificationSafetyVerdict: 'pass' | 'flag' | 'reject' | null; +} +``` + +--- + +## Error handling + +- Pipeline halts and returns `pending_human_review` if `ContentSafetyAgent` returns `flag`. +- Pipeline retries `QualityEvalAgent` once on network error; on second failure, logs and continues with `score: null` → human review. +- All agent results are stored on the listing doc for audit trail. +- Author always receives a notification (approved / rejected / pending). + +--- + +## MCP tool surface + +```typescript +jarvisjr.marketplace.submitForReview(listingId: string): CertificationResult +jarvisjr.marketplace.getCertificationStatus(listingId: string): CertificationStatus +jarvisjr.marketplace.listPendingReview(limit?: number): MarketplaceListingDoc[] +``` + +--- + +## Implementation checklist + +- [ ] `SubmissionIngestionAgent` — validate required fields against schema +- [ ] `ContentSafetyAgent` — call extraction-service `triage` task, map classes to policy +- [ ] `QualityEvalAgent` — `POST /jarvis/sessions/eval` internal endpoint + scoring logic +- [ ] `CertificationDecisionAgent` — decision tree + `PUT /marketplace/listings/:id` update +- [ ] `POST /marketplace/listings/:id/submit-for-review` trigger endpoint +- [ ] MCP tool registrations in `backend/src/modules/marketplace/routes.ts` +- [ ] Author notification via `platform-service /push-triggers`