diff --git a/apps/x/packages/core/src/application/assistant/instructions.ts b/apps/x/packages/core/src/application/assistant/instructions.ts index b7836949..9429d849 100644 --- a/apps/x/packages/core/src/application/assistant/instructions.ts +++ b/apps/x/packages/core/src/application/assistant/instructions.ts @@ -24,6 +24,8 @@ Rowboat is an agentic assistant for everyday work - emails, meetings, projects, **Email Drafting:** When users ask you to draft emails or respond to emails, load the \`draft-emails\` skill first. It provides structured guidance for processing emails, gathering context from calendar and knowledge base, and creating well-informed draft responses. +**Meeting Prep:** When users ask you to prepare for a meeting, prep for a call, or brief them on attendees, load the \`meeting-prep\` skill first. It provides structured guidance for gathering context about attendees from the knowledge base and creating useful meeting briefs. + ## Memory That Compounds Unlike other AI assistants that start cold every session, you have access to a live knowledge graph that updates itself from Gmail, calendar, and meeting notes (Google Meet, Granola, Fireflies). This isn't just summaries - it's structured extraction of decisions, commitments, open questions, and context, routed to long-lived notes for each person, project, and topic. diff --git a/apps/x/packages/core/src/application/assistant/skills/index.ts b/apps/x/packages/core/src/application/assistant/skills/index.ts index 6a43dc4e..f71b1991 100644 --- a/apps/x/packages/core/src/application/assistant/skills/index.ts +++ b/apps/x/packages/core/src/application/assistant/skills/index.ts @@ -4,6 +4,7 @@ import builtinToolsSkill from "./builtin-tools/skill.js"; import deletionGuardrailsSkill from "./deletion-guardrails/skill.js"; import draftEmailsSkill from "./draft-emails/skill.js"; import mcpIntegrationSkill from "./mcp-integration/skill.js"; +import meetingPrepSkill from "./meeting-prep/skill.js"; import workflowAuthoringSkill from "./workflow-authoring/skill.js"; import workflowRunOpsSkill from "./workflow-run-ops/skill.js"; @@ -33,6 +34,13 @@ const definitions: SkillDefinition[] = [ summary: "Process incoming emails and create draft responses using calendar and knowledge base for context.", content: draftEmailsSkill, }, + { + id: "meeting-prep", + title: "Meeting Prep", + folder: "meeting-prep", + summary: "Prepare for meetings by gathering context about attendees from the knowledge base.", + content: meetingPrepSkill, + }, { id: "workflow-authoring", title: "Workflow Authoring", diff --git a/apps/x/packages/core/src/application/assistant/skills/meeting-prep/skill.ts b/apps/x/packages/core/src/application/assistant/skills/meeting-prep/skill.ts new file mode 100644 index 00000000..3a38e715 --- /dev/null +++ b/apps/x/packages/core/src/application/assistant/skills/meeting-prep/skill.ts @@ -0,0 +1,165 @@ +export const skill = String.raw` +# Meeting Prep Skill + +You are helping the user prepare for meetings by gathering context from their knowledge base and calendar. + +## CRITICAL: Always Look Up Context First + +**BEFORE creating any meeting brief, you MUST look up the attendees in the knowledge base.** + +**PATH REQUIREMENT:** Always use \`knowledge/\` as the path (not empty, not root, not \`~/.rowboat\`). +- **WRONG:** \`path: ""\` or \`path: "."\` +- **CORRECT:** \`path: "knowledge/"\` + +When the user asks to prep for a meeting or mentions attendees: + +1. **STOP** - Do not create a generic brief +2. **SEARCH** - Look up each attendee in the knowledge base: + \`\`\` + workspace-grep({ pattern: "Attendee Name", path: "knowledge/" }) + \`\`\` +3. **READ** - Read their notes to understand who they are: + \`\`\` + workspace-readFile("knowledge/People/Attendee Name.md") + workspace-readFile("knowledge/Organizations/Their Company.md") + \`\`\` +4. **UNDERSTAND** - Extract their role, organization, relationship history, past interactions, open items +5. **THEN BRIEF** - Only now create the meeting brief, using this context + +**DO NOT** skip this step. **DO NOT** provide generic briefs. If you don't look up the context first, you will give a useless generic response. + +## Key Principles + +**Ask, don't guess:** +- If the user's intent is unclear, ASK them which meeting they want to prep for +- If there are multiple upcoming meetings, ASK which one (or offer to prep all) +- **WRONG:** "Here's a generic meeting prep template" +- **CORRECT:** "I see you have meetings with Sarah (2pm) and John (4pm) today. Which one would you like me to prep?" + +**Be thorough, not generic:** +- Once you know the meeting, gather ALL relevant context from knowledge base +- Include specific history, open items, and context - not generic talking points +- Reference actual past interactions and commitments + +## Processing Flow + +### Step 1: Identify the Meeting + +If the user specifies a meeting: +- Look it up in \`calendar_sync/\` folder +- Parse the event details + +If the user says "prep me for my next meeting" or similar: +- List upcoming events from \`calendar_sync/\` +- Find the next meeting with external attendees +- Confirm with the user if unclear + +### Step 2: Parse Calendar Event + +Read the calendar event to extract: +- Meeting title (summary) +- Start/end time +- Attendees (names and emails) +- Description/agenda if available + +### Step 3: Gather Context from Knowledge Base + +For each attendee, search the knowledge base (path MUST be \`knowledge/\`): + +**Search People notes:** +\`\`\` +workspace-grep({ pattern: "attendee_name", path: "knowledge/People/" }) +workspace-grep({ pattern: "attendee_email", path: "knowledge/People/" }) +\`\`\` + +If a person note exists, read it: +\`\`\` +workspace-readFile("knowledge/People/Attendee Name.md") +\`\`\` + +Extract: +- Their role/title +- Company/organization +- Key facts about them +- Previous interactions +- Open items + +**Search Organization notes:** +\`\`\` +workspace-grep({ pattern: "company_name", path: "knowledge/Organizations/" }) +\`\`\` + +**Search Projects:** +\`\`\` +workspace-grep({ pattern: "attendee_name", path: "knowledge/Projects/" }) +workspace-grep({ pattern: "company_name", path: "knowledge/Projects/" }) +\`\`\` + +### Step 4: Create Meeting Brief + +Create a brief with this format: + +\`\`\`markdown +๐Ÿ“‹ +Meeting Brief: {Attendee Name} +{Time} today ยท {Company} + +About {First Name} +{Role at company}. {Key background - 1-2 sentences}. {What they care about or focus on}. + +Your History +- {Date}: {Brief description of interaction/outcome} +- {Date}: {Brief description} +- {Date}: {Brief description} + +Open Items +- {Action item} (they asked {date}) +- {Action item} + +Suggested Talking Points +- {Concrete suggestion based on history} +- {Reference relevant entities with [[wiki-links]]} +\`\`\` + +**Example:** +\`\`\`markdown +๐Ÿ“‹ +Meeting Brief: Sarah Chen +2:00 PM today ยท Horizon Ventures + +About Sarah +Partner at Horizon Ventures. Led investments in WorkOS and Segment. Very focused on unit economics. + +Your History +- Jan 15: Partner meeting โ€” positive reception +- Jan 12: Sent updated deck with cohort analysis +- Jan 8: First pitch โ€” she loved the 125% NRR + +Open Items +- Send updated financial model (she asked Jan 15) +- Discuss term sheet timeline + +Suggested Talking Points +- Address her question about CAC by channel +- Mention [[TechFlow]] expansion closed ($120K ARR) +\`\`\` + +**Briefing Guidelines:** +- Use \`[[Name]]\` wiki-link syntax for cross-references to people, projects, orgs +- Keep "About" section concise - 2-3 sentences max +- History should be reverse chronological (most recent first) +- Limit to 3-5 most relevant history items +- Open items should be actionable and specific +- Talking points should be concrete, not generic +- If no notes exist for a person, mention that and offer to create one + +## Important Notes + +- Only prep for meetings with external attendees +- Skip internal calendar blocks (DND, Focus Time, Lunch, etc.) +- For meetings with multiple attendees, create sections for each key person +- Prioritize recent interactions (last 30 days) in the history section +- If an attendee has no notes, suggest what you'd want to capture about them +`; + +export default skill;