diff --git a/apps/rowboat/app/lib/prebuilt-cards/Meeting Prep Assistant.json b/apps/rowboat/app/lib/prebuilt-cards/Meeting Prep Assistant.json deleted file mode 100644 index 2bf69029..00000000 --- a/apps/rowboat/app/lib/prebuilt-cards/Meeting Prep Assistant.json +++ /dev/null @@ -1,354 +0,0 @@ -{ - "category": "Work Productivity", - "agents": [ - { - "name": "Meeting Prep Hub", - "type": "conversation", - "description": "Hub agent to orchestrate meeting guest research and email delivery.", - "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nYou are the hub agent responsible for orchestrating the process of researching meeting guests and sending a summary to the user via email.\n\n---\n## āš™ļø Steps to Follow:\n1. Greet the user and ask for the Google Calendar invite details (event name, date, or link) and their email address.\n2. Call [@agent:Calendar Event Agent](#mention) with the provided invite details to extract guest information.\n3. Wait for the guest list from Calendar Event Agent.\n4. Call [@agent:Research Agent](#mention) to perform DuckDuckGo research on each guest.\n5. Wait for the research summary from Research Agent.\n6. Call [@agent:Email Agent](#mention) to send the summary to the user's email.\n7. Inform the user when the research summary has been sent.\n\n---\n## šŸŽÆ Scope:\nāœ… In Scope:\n- Orchestrating the workflow for meeting guest research and email delivery.\n\nāŒ Out of Scope:\n- Directly researching guests or sending emails (handled by sub-agents).\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Always confirm the invite details and email address with the user.\n- Ensure all steps are completed in sequence.\n\n🚫 Don'ts:\n- Do not perform research or send emails directly.\n- Do not skip any step in the workflow.\n- Do not mention internal agent names to the user.\n- Do not say 'connecting you to another agent'.\n- CRITICAL: Only transfer to one agent at a time and wait for its response before proceeding.\n\n# Examples\n- **User** : I have a meeting invite for 'Q3 Planning' on July 10. My email is user@email.com\n - **Agent actions**: Call [@agent:Calendar Event Agent](#mention)\n\n- **Agent receives guest list** :\n - **Agent actions**: Call [@agent:Research Agent](#mention)\n\n- **Agent receives research summary** :\n - **Agent actions**: Call [@agent:Email Agent](#mention)\n\n- **Agent receives email confirmation** :\n - **Agent response**: The research summary has been sent to your email.", - "examples": "- **User** : I have a meeting invite for 'Q3 Planning' on July 10. My email is user@email.com\n - **Agent actions**: Call [@agent:Calendar Event Agent](#mention)\n\n- **Agent receives guest list** :\n - **Agent actions**: Call [@agent:Research Agent](#mention)\n\n- **Agent receives research summary** :\n - **Agent actions**: Call [@agent:Email Agent](#mention)\n\n- **Agent receives email confirmation** :\n - **Agent response**: The research summary has been sent to your email.", - "model": "google/gemini-2.5-flash", - "toggleAble": true, - "ragReturnType": "chunks", - "ragK": 3, - "outputVisibility": "user_facing", - "controlType": "retain" - }, - { - "name": "Calendar Event Agent", - "type": "conversation", - "description": "Extracts guest details from a provided Google Calendar invite.", - "disabled": false, - "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nExtract guest (attendee) details from the provided Google Calendar invite information.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive the event name, date, or link from the parent agent.\n2. Use [@tool:Find event](#mention) to fetch the event and extract the list of guests (names and emails).\n3. Return the guest list to the parent agent.\n\n---\n## šŸŽÆ Scope:\nāœ… In Scope:\n- Fetching event details and extracting guest information.\n\nāŒ Out of Scope:\n- Researching guests.\n- Sending emails.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Return all relevant guest details.\n\n🚫 Don'ts:\n- Do not perform research or send emails.\n- Do not interact with the user directly.", - "examples": "- **Parent agent** : Get guests for 'Q3 Planning' on July 10.\n - **Agent actions**: Call [@tool:Find event](#mention)\n - **Agent response**: [List of guests with names and emails]", - "model": "google/gemini-2.5-flash", - "locked": false, - "toggleAble": true, - "ragReturnType": "chunks", - "ragK": 3, - "outputVisibility": "internal", - "controlType": "relinquish_to_parent", - "maxCallsPerParentAgent": 3 - }, - { - "name": "Research Agent", - "type": "conversation", - "description": "Performs DuckDuckGo searches on each guest and summarizes the findings.", - "disabled": false, - "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nResearch each guest using DuckDuckGo and summarize the findings.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive a list of guest names and emails from the parent agent.\n2. For each guest, use [@tool:Composio DuckDuckGo Search](#mention) to find relevant information.\n3. Summarize the findings for each guest (role, company, notable info).\n4. Return the research summary to the parent agent.\n\n---\n## šŸŽÆ Scope:\nāœ… In Scope:\n- Researching guests using DuckDuckGo.\n\nāŒ Out of Scope:\n- Fetching event details.\n- Sending emails.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Provide concise, relevant guest profiles.\n\n🚫 Don'ts:\n- Do not fabricate information.\n- Do not interact with the user directly.", - "examples": "- **Parent agent** : Research guests: Alice Smith (alice@email.com), Bob Lee (bob@email.com)\n - **Agent actions**: Call [@tool:Composio DuckDuckGo Search](#mention) for each guest\n - **Agent response**: Alice Smith: [summary], Bob Lee: [summary]", - "model": "google/gemini-2.5-flash", - "locked": false, - "toggleAble": true, - "ragReturnType": "chunks", - "ragK": 3, - "outputVisibility": "internal", - "controlType": "relinquish_to_parent", - "maxCallsPerParentAgent": 3 - }, - { - "name": "Email Agent", - "type": "conversation", - "description": "Sends the research summary to the user's email address.", - "disabled": false, - "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nSend the provided research summary to the user's email address.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive the research summary and recipient email from the parent agent.\n2. Use [@tool:Send Email](#mention) to send the summary.\n3. Confirm delivery to the parent agent.\n\n---\n## šŸŽÆ Scope:\nāœ… In Scope:\n- Sending research summaries via email.\n\nāŒ Out of Scope:\n- Fetching event details.\n- Researching guests.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Ensure the summary is sent to the correct email.\n\n🚫 Don'ts:\n- Do not interact with the user directly.", - "examples": "- **Parent agent** : Send summary to user@email.com: [summary text]\n - **Agent actions**: Call [@tool:Send Email](#mention)\n - **Agent response**: Email sent confirmation.", - "model": "google/gemini-2.5-flash", - "locked": false, - "toggleAble": true, - "ragReturnType": "chunks", - "ragK": 3, - "outputVisibility": "internal", - "controlType": "relinquish_to_parent", - "maxCallsPerParentAgent": 3 - } - ], - "prompts": [], - "tools": [ - { - "name": "Find event", - "description": "Finds events in a specified google calendar using text query, time ranges, and event types.", - "mockTool": false, - "parameters": { - "type": "object", - "properties": { - "calendar_id": { - "default": "primary", - "description": "Identifier of the Google Calendar to query.", - "examples": [ - "primary", - "user@example.com", - "abc...@group.calendar.google.com" - ], - "title": "Calendar Id", - "type": "string" - }, - "event_types": { - "default": [ - "birthday", - "default", - "focusTime", - "outOfOffice", - "workingLocation" - ], - "description": "Event types to include.", - "examples": [ - "default", - "focusTime", - "outOfOffice" - ], - "items": { - "enum": [ - "birthday", - "default", - "focusTime", - "outOfOffice", - "workingLocation" - ], - "type": "string" - }, - "title": "Event Types", - "type": "array" - }, - "max_results": { - "default": 10, - "description": "Maximum number of events per page (1-2500).", - "title": "Max Results", - "type": "integer" - }, - "order_by": { - "default": null, - "description": "Order of events: 'startTime' or 'updated'.", - "examples": [ - "startTime", - "updated" - ], - "nullable": true, - "title": "Order By", - "type": "string" - }, - "page_token": { - "default": null, - "description": "Token for pagination.", - "nullable": true, - "title": "Page Token", - "type": "string" - }, - "query": { - "default": null, - "description": "Free-text search terms to find events.", - "examples": [ - "Project Alpha Review", - "Birthday Party" - ], - "nullable": true, - "title": "Query", - "type": "string" - }, - "show_deleted": { - "default": null, - "description": "Include deleted events.", - "nullable": true, - "title": "Show Deleted", - "type": "boolean" - }, - "single_events": { - "default": true, - "description": "Expand recurring events into individual instances.", - "title": "Single Events", - "type": "boolean" - }, - "timeMax": { - "default": null, - "description": "Upper bound for event's start time.", - "examples": [ - "2024-12-31T23:59:59Z" - ], - "nullable": true, - "title": "Time Max", - "type": "string" - }, - "timeMin": { - "default": null, - "description": "Lower bound for event's end time.", - "examples": [ - "2024-01-01T00:00:00Z" - ], - "nullable": true, - "title": "Time Min", - "type": "string" - }, - "updated_min": { - "default": null, - "description": "Lower bound for event's last modification time.", - "examples": [ - "2024-07-01T00:00:00Z" - ], - "nullable": true, - "title": "Updated Min", - "type": "string" - } - }, - "required": [] - }, - "isComposio": true, - "composioData": { - "slug": "GOOGLECALENDAR_FIND_EVENT", - "noAuth": false, - "toolkitName": "googlecalendar", - "toolkitSlug": "googlecalendar", - "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master/google-calendar.svg" - } - }, - { - "name": "Composio DuckDuckGo Search", - "description": "Performs web searches using DuckDuckGo to retrieve relevant information.", - "mockTool": false, - "parameters": { - "type": "object", - "properties": { - "query": { - "description": "The search query for DuckDuckGo.", - "examples": [ - "Python programming" - ], - "title": "Query", - "type": "string" - } - }, - "required": [ - "query" - ] - }, - "isComposio": true, - "composioData": { - "slug": "COMPOSIO_SEARCH_DUCK_DUCK_GO_SEARCH", - "noAuth": true, - "toolkitName": "composio_search", - "toolkitSlug": "composio_search", - "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master//composio-logo.png" - } - }, - { - "name": "Send Email", - "description": "Sends an email via Gmail using the authenticated user's Google profile.", - "mockTool": false, - "parameters": { - "type": "object", - "properties": { - "attachment": { - "additionalProperties": false, - "description": "File to attach; ensure s3key, mimetype, and name are set if provided.", - "file_uploadable": true, - "properties": { - "mimetype": { - "title": "Mimetype", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "s3key": { - "title": "S3Key", - "type": "string" - } - }, - "required": [ - "name", - "mimetype", - "s3key" - ], - "title": "FileUploadable", - "type": "object" - }, - "bcc": { - "default": [], - "description": "BCC recipients' email addresses.", - "items": { - "type": "string" - }, - "title": "Bcc", - "type": "array" - }, - "body": { - "description": "Email content (plain text or HTML).", - "examples": [ - "Hello team, let's discuss the project updates tomorrow." - ], - "title": "Body", - "type": "string" - }, - "cc": { - "default": [], - "description": "CC recipients' email addresses.", - "items": { - "type": "string" - }, - "title": "Cc", - "type": "array" - }, - "extra_recipients": { - "default": [], - "description": "Additional 'To' recipients' email addresses.", - "items": { - "type": "string" - }, - "title": "Extra Recipients", - "type": "array" - }, - "is_html": { - "default": false, - "description": "Set to True if the email body contains HTML tags.", - "title": "Is Html", - "type": "boolean" - }, - "recipient_email": { - "description": "Primary recipient's email address.", - "examples": [ - "john@doe.com" - ], - "title": "Recipient Email", - "type": "string" - }, - "subject": { - "default": null, - "description": "Subject line of the email.", - "examples": [ - "Project Update Meeting" - ], - "nullable": true, - "title": "Subject", - "type": "string" - }, - "user_id": { - "default": "me", - "description": "User's email address; 'me' refers to the authenticated user.", - "examples": [ - "user@example.com", - "me" - ], - "title": "User Id", - "type": "string" - } - }, - "required": [ - "recipient_email", - "body" - ] - }, - "isComposio": true, - "composioData": { - "slug": "GMAIL_SEND_EMAIL", - "noAuth": false, - "toolkitName": "gmail", - "toolkitSlug": "gmail", - "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master/gmail.svg" - } - } - ], - "startAgent": "Meeting Prep Hub", - "lastUpdatedAt": "2025-09-07T17:06:05.564Z", - "name": "Meeting Prep", - "description": "Research meeting attendees and send summary to Slack" -} diff --git a/apps/rowboat/app/lib/prebuilt-cards/github-issue-to-slack.json b/apps/rowboat/app/lib/prebuilt-cards/github-issue-to-slack.json new file mode 100644 index 00000000..39da884d --- /dev/null +++ b/apps/rowboat/app/lib/prebuilt-cards/github-issue-to-slack.json @@ -0,0 +1,119 @@ +{ + "agents": [ + { + "name": "GitHub Issue to Slack Hub", + "type": "conversation", + "description": "Receives new GitHub issue details and sends a formatted message to Slack.", + "disabled": false, + "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nYou are the assistant responsible for sending new GitHub issue details to Slack.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive a new GitHub issue payload (via trigger).\n2. Extract the relevant details: issue title, description, URL, creator, and any labels.\n3. Format a Slack message summarizing the issue (include all details and a direct link).\n4. Use [@tool:Send message](#mention) to post the message to the specified Slack channel.\n5. Respond with 'done!' to indicate completion.\n\n---\n## šŸŽÆ Scope:\nāœ… In Scope:\n- Formatting and sending Slack messages for new GitHub issues.\n\nāŒ Out of Scope:\n- Handling other GitHub events.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Ensure the message is clear and includes all relevant details.\n- Use markdown formatting for readability.\n\n🚫 Don'ts:\n- Do not process non-issue events.\n- CRITICAL: Only call the Slack tool once per issue event.\n\n# Examples\n- **Trigger** : New GitHub issue: 'Bug: Login fails', description: 'User cannot log in', url: 'https://github.com/org/repo/issues/123', creator: 'alice', labels: ['bug']\n - **Agent actions**: Call [@tool:Send message](#mention)\n - **Agent response**: done!", + "model": "google/gemini-2.5-flash", + "locked": false, + "toggleAble": true, + "ragReturnType": "chunks", + "ragK": 3, + "outputVisibility": "user_facing", + "controlType": "retain", + "maxCallsPerParentAgent": 3 + } + ], + "prompts": [ + { + "name": "Slack Channel", + "type": "base_prompt", + "prompt": "" + } + ], + "tools": [ + { + "name": "Send message", + "description": "Posts a message to a slack channel, direct message, or private group; requires content via `text`, `blocks`, or `attachments`.", + "mockTool": false, + "parameters": { + "type": "object", + "properties": { + "as_user": { + "description": "Post as the authenticated user instead of as a bot. Defaults to `false`. If `true`, `username`, `icon_emoji`, and `icon_url` are ignored. If `false`, the message is posted as a bot, allowing appearance customization.", + "type": "boolean" + }, + "attachments": { + "description": "URL-encoded JSON array of message attachments, a legacy method for rich content. See Slack API documentation for structure.", + "type": "string" + }, + "blocks": { + "description": "DEPRECATED: Use `markdown_text` field instead. URL-encoded JSON array of layout blocks for rich/interactive messages. See Slack API Block Kit docs for structure.", + "type": "string" + }, + "channel": { + "description": "ID or name of the channel, private group, or IM channel to send the message to.", + "type": "string" + }, + "icon_emoji": { + "description": "Emoji for bot's icon (e.g., ':robot_face:'). Overrides `icon_url`. Applies if `as_user` is `false`.", + "type": "string" + }, + "icon_url": { + "description": "Image URL for bot's icon (must be HTTPS). Applies if `as_user` is `false`.", + "type": "string" + }, + "link_names": { + "description": "Automatically hyperlink channel names (e.g., #channel) and usernames (e.g., @user) in message text. Defaults to `false` for bot messages.", + "type": "boolean" + }, + "markdown_text": { + "description": "PREFERRED: Write your message in markdown for nicely formatted display. Supports: headers (# ## ###), bold (**text** or __text__), italic (*text* or _text_), strikethrough (~~text~~), inline code (`code`), code blocks (```), links ([text](url)), block quotes (>), lists (- item, 1. item), dividers (--- or ***), context blocks (:::context with images), and section buttons (:::section-button). IMPORTANT: Use \\\\n for line breaks (e.g., 'Line 1\\\\nLine 2'), not actual newlines. USER MENTIONS: To tag users, use their user ID with <@USER_ID> format (e.g., <@U1234567890>), not username.", + "type": "string" + }, + "mrkdwn": { + "description": "Disable Slack's markdown for `text` field if `false`. Default `true` (allows *bold*, _italic_, etc.).", + "type": "boolean" + }, + "parse": { + "description": "Message text parsing behavior. Default `none` (no special parsing). `full` parses as user-typed (links @mentions, #channels). See Slack API docs for details.", + "type": "string" + }, + "reply_broadcast": { + "description": "If `true` for a threaded reply, also posts to main channel. Defaults to `false`.", + "type": "boolean" + }, + "text": { + "description": "DEPRECATED: This sends raw text only, use markdown_text field. Primary textual content. Recommended fallback if using `blocks` or `attachments`. Supports mrkdwn unless `mrkdwn` is `false`.", + "type": "string" + }, + "thread_ts": { + "description": "Timestamp (`ts`) of an existing message to make this a threaded reply. Use `ts` of the parent message, not another reply. Example: '1476746824.000004'.", + "type": "string" + }, + "unfurl_links": { + "description": "Enable unfurling of text-based URLs. Defaults `false` for bots, `true` if `as_user` is `true`.", + "type": "boolean" + }, + "unfurl_media": { + "description": "Disable unfurling of media content from URLs if `false`. Defaults to `true`.", + "type": "boolean" + }, + "username": { + "description": "Bot's name in Slack (max 80 chars). Applies if `as_user` is `false`.", + "type": "string" + } + }, + "required": [ + "channel" + ] + }, + "isComposio": true, + "composioData": { + "slug": "SLACK_SEND_MESSAGE", + "noAuth": false, + "toolkitName": "slack", + "toolkitSlug": "slack", + "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master/slack.svg" + } + } + ], + "pipelines": [], + "startAgent": "GitHub Issue to Slack Hub", + "lastUpdatedAt": "2025-09-12T13:46:12.039Z", + "name": "GitHub Issue to Slack", + "description": "Assistant that sends a formatted Slack message with GitHub issue details when a issue is opened or updated.", + "category": "Developer Productivity" +} \ No newline at end of file diff --git a/apps/rowboat/app/lib/prebuilt-cards/github-pr-to-slack.json b/apps/rowboat/app/lib/prebuilt-cards/github-pr-to-slack.json new file mode 100644 index 00000000..863c8e82 --- /dev/null +++ b/apps/rowboat/app/lib/prebuilt-cards/github-pr-to-slack.json @@ -0,0 +1,133 @@ +{ + "agents": [ + { + "name": "PR to Slack Agent", + "type": "conversation", + "description": "Receives PR event details and sends a formatted Slack message to a specified channel.", + "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nYou are an internal agent that receives pull request (PR) event details and sends a Slack message with the PR information.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive PR event details (title, author, URL, description, etc.) and the Slack channel name.\n2. Format a clear, concise Slack message summarizing the PR (e.g., title, author, link, and description).\n3. Use [@tool:Send message](#mention) to post the message to the specified Slack channel.\n4. Return confirmation of message sent.\n\n---\n## šŸŽÆ Scope:\nāœ… In Scope:\n- Formatting PR details for Slack.\n- Sending messages to Slack channels.\n\nāŒ Out of Scope:\n- Handling PR events directly (trigger is external).\n- User interaction or responding to user queries.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Ensure the Slack message is clear and includes a link to the PR.\n- Use markdown formatting for readability.\n\n🚫 Don'ts:\n- Do not interact with users.\n- Do not process events other than PRs.\n\n# Examples\n- **Trigger** : PR opened: Title: \"Add new feature\", Author: \"alice\", URL: \"https://github.com/org/repo/pull/123\", Description: \"Implements feature X.\"\n - **Agent actions**: Call [@tool:Send message](#mention)\n - **Agent response**: Slack message sent: \"*New PR Opened*\n*Title:* Add new feature\n*Author:* alice\n*Description:* Implements feature X.\n\"\n\n- **Trigger** : PR merged: Title: \"Fix bug\", Author: \"bob\", URL: \"https://github.com/org/repo/pull/456\", Description: \"Fixes Y bug.\"\n - **Agent actions**: Call [@tool:Send message](#mention)\n - **Agent response**: Slack message sent: \"*PR Merged*\n*Title:* Fix bug\n*Author:* bob\n*Description:* Fixes Y bug.\n\"", + "model": "google/gemini-2.5-flash", + "toggleAble": true, + "ragReturnType": "chunks", + "ragK": 3, + "outputVisibility": "internal", + "controlType": "relinquish_to_parent", + "maxCallsPerParentAgent": 1 + } + ], + "prompts": [ + { + "name": "Slack Channel", + "type": "base_prompt", + "prompt": "" + } + ], + "tools": [ + { + "name": "Send message", + "description": "Posts a message to a slack channel, direct message, or private group; requires content via `text`, `blocks`, or `attachments`.", + "mockTool": false, + "parameters": { + "type": "object", + "properties": { + "as_user": { + "description": "Post as the authenticated user instead of as a bot. Defaults to `false`. If `true`, `username`, `icon_emoji`, and `icon_url` are ignored. If `false`, the message is posted as a bot, allowing appearance customization.", + "title": "As User", + "type": "boolean" + }, + "attachments": { + "description": "URL-encoded JSON array of message attachments, a legacy method for rich content. See Slack API documentation for structure.", + "title": "Attachments", + "type": "string" + }, + "blocks": { + "description": "DEPRECATED: Use `markdown_text` field instead. URL-encoded JSON array of layout blocks for rich/interactive messages. See Slack API Block Kit docs for structure.", + "title": "Blocks", + "type": "string" + }, + "channel": { + "description": "ID or name of the channel, private group, or IM channel to send the message to.", + "title": "Channel", + "type": "string" + }, + "icon_emoji": { + "description": "Emoji for bot's icon (e.g., ':robot_face:'). Overrides `icon_url`. Applies if `as_user` is `false`.", + "title": "Icon Emoji", + "type": "string" + }, + "icon_url": { + "description": "Image URL for bot's icon (must be HTTPS). Applies if `as_user` is `false`.", + "title": "Icon Url", + "type": "string" + }, + "link_names": { + "description": "Automatically hyperlink channel names (e.g., #channel) and usernames (e.g., @user) in message text. Defaults to `false` for bot messages.", + "title": "Link Names", + "type": "boolean" + }, + "markdown_text": { + "description": "PREFERRED: Write your message in markdown for nicely formatted display. Supports: headers (# ## ###), bold (**text** or __text__), italic (*text* or _text_), strikethrough (~~text~~), inline code (`code`), code blocks (```), links ([text](url)), block quotes (>), lists (- item, 1. item), dividers (--- or ***), context blocks (:::context with images), and section buttons (:::section-button). IMPORTANT: Use \\\\n for line breaks (e.g., 'Line 1\\\\nLine 2'), not actual newlines. USER MENTIONS: To tag users, use their user ID with <@USER_ID> format (e.g., <@U1234567890>), not username.", + "title": "Markdown Text", + "type": "string" + }, + "mrkdwn": { + "description": "Disable Slack's markdown for `text` field if `false`. Default `true` (allows *bold*, _italic_, etc.).", + "title": "Mrkdwn", + "type": "boolean" + }, + "parse": { + "description": "Message text parsing behavior. Default `none` (no special parsing). `full` parses as user-typed (links @mentions, #channels). See Slack API docs for details.", + "title": "Parse", + "type": "string" + }, + "reply_broadcast": { + "description": "If `true` for a threaded reply, also posts to main channel. Defaults to `false`.", + "title": "Reply Broadcast", + "type": "boolean" + }, + "text": { + "description": "DEPRECATED: This sends raw text only, use markdown_text field. Primary textual content. Recommended fallback if using `blocks` or `attachments`. Supports mrkdwn unless `mrkdwn` is `false`.", + "title": "Text", + "type": "string" + }, + "thread_ts": { + "description": "Timestamp (`ts`) of an existing message to make this a threaded reply. Use `ts` of the parent message, not another reply. Example: '1476746824.000004'.", + "title": "Thread Ts", + "type": "string" + }, + "unfurl_links": { + "description": "Enable unfurling of text-based URLs. Defaults `false` for bots, `true` if `as_user` is `true`.", + "title": "Unfurl Links", + "type": "boolean" + }, + "unfurl_media": { + "description": "Disable unfurling of media content from URLs if `false`. Defaults to `true`.", + "title": "Unfurl Media", + "type": "boolean" + }, + "username": { + "description": "Bot's name in Slack (max 80 chars). Applies if `as_user` is `false`.", + "title": "Username", + "type": "string" + } + }, + "required": [ + "channel" + ] + }, + "isComposio": true, + "composioData": { + "slug": "SLACK_SEND_MESSAGE", + "noAuth": false, + "toolkitName": "slack", + "toolkitSlug": "slack", + "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master/slack.svg" + } + } + ], + "pipelines": [], + "startAgent": "PR to Slack Agent", + "lastUpdatedAt": "2025-09-12T06:30:34.203Z", + "name": "GitHub PR to Slack", + "description": "Assistant that sends a formatted Slack message with PR details when a PR is opened or merged.", + "category": "Developer Productivity" +} \ No newline at end of file diff --git a/apps/rowboat/app/lib/prebuilt-cards/index.ts b/apps/rowboat/app/lib/prebuilt-cards/index.ts index b8080c80..10d39ee6 100644 --- a/apps/rowboat/app/lib/prebuilt-cards/index.ts +++ b/apps/rowboat/app/lib/prebuilt-cards/index.ts @@ -3,11 +3,13 @@ import githubDataToSpreadsheet from './github-data-to-spreadsheet.json'; import interviewScheduler from './interview-scheduler.json'; -import meetingPrepAssistant from './Meeting Prep Assistant.json'; -import redditOnSlack from './Reddit on Slack.json'; +import meetingPrepAssistant from './meeting-prep-assistant.json'; +import redditOnSlack from './reddit-on-slack.json'; import twitterSentiment from './twitter-sentiment.json'; -import tweetWithGeneratedImage from './Tweet with generated image.json'; +import tweetWithGeneratedImage from './tweet-with-generated-image.json'; import customerSupport from './customer-support.json'; +import githubIssueToSlack from './github-issue-to-slack.json'; +import githubPrToSlack from './github-pr-to-slack.json'; // Keep keys consistent with prior file basenames to avoid breaking links. export const prebuiltTemplates = { @@ -18,5 +20,7 @@ export const prebuiltTemplates = { 'Twitter Sentiment': twitterSentiment, 'Tweet with generated image': tweetWithGeneratedImage, 'Customer Support': customerSupport, + 'GitHub Issue to Slack': githubIssueToSlack, + 'GitHub PR to Slack': githubPrToSlack, }; diff --git a/apps/rowboat/app/lib/prebuilt-cards/meeting-prep-assistant.json b/apps/rowboat/app/lib/prebuilt-cards/meeting-prep-assistant.json new file mode 100644 index 00000000..ddf724db --- /dev/null +++ b/apps/rowboat/app/lib/prebuilt-cards/meeting-prep-assistant.json @@ -0,0 +1,242 @@ +{ + "agents": [ + { + "name": "Research Guests Agent", + "type": "pipeline", + "description": "Researches each guest in the calendar invite using Exa Answer and compiles a summary.", + "disabled": false, + "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nYou are a pipeline agent that researches each guest in a Google Calendar invite.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive a list of guest names and emails from the calendar invite.\n2. For each guest, use [@tool:Exa Answer](#mention) to search for public information about them (e.g., 'Who is [Name] [Email]?').\n3. Summarize the findings for each guest in 2-3 sentences.\n4. Return a list of guest research summaries for the next step.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Be concise and factual.\n- If no information is found, state 'No public information found.'\n🚫 Don'ts:\n- Do not fabricate information.\n- Do not send emails or interact with the user.", + "model": "google/gemini-2.5-flash", + "locked": false, + "toggleAble": true, + "ragReturnType": "chunks", + "ragK": 3, + "outputVisibility": "internal", + "controlType": "relinquish_to_parent", + "maxCallsPerParentAgent": 3 + }, + { + "name": "Compile Email Agent", + "type": "pipeline", + "description": "Formats the guest research summaries into a clear email body.", + "disabled": false, + "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nYou are a pipeline agent that formats guest research into an email body.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive the list of guest research summaries.\n2. Format the summaries into a readable email body, with each guest's name and their summary.\n3. Add a subject line: 'Meeting Guest Research Summary'.\n4. Return the subject and body for the next step.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Use clear formatting (e.g., bullet points or sections per guest).\n🚫 Don'ts:\n- Do not send emails or interact with the user.", + "model": "google/gemini-2.5-flash", + "locked": false, + "toggleAble": true, + "ragReturnType": "chunks", + "ragK": 3, + "outputVisibility": "internal", + "controlType": "relinquish_to_parent", + "maxCallsPerParentAgent": 3 + }, + { + "name": "Send Email Agent", + "type": "pipeline", + "description": "Sends the compiled guest research summary to the user's email using Gmail.", + "disabled": false, + "instructions": "## šŸ§‘ā€šŸ’¼ Role:\nYou are a pipeline agent that sends the guest research summary email.\n\n---\n## āš™ļø Steps to Follow:\n1. Receive the subject, body, and recipient email address.\n2. Use [@tool:Send Email](#mention) to send the email.\n3. Return confirmation of sending.\n\n---\n## šŸ“‹ Guidelines:\nāœ”ļø Dos:\n- Ensure the email is sent to the correct address.\n🚫 Don'ts:\n- Do not perform research or format the email body.", + "model": "google/gemini-2.5-flash", + "locked": false, + "toggleAble": true, + "ragReturnType": "chunks", + "ragK": 3, + "outputVisibility": "internal", + "controlType": "relinquish_to_parent", + "maxCallsPerParentAgent": 3 + } + ], + "prompts": [ + { + "name": "User's Email", + "type": "base_prompt", + "prompt": "" + } + ], + "tools": [ + { + "name": "Exa Answer", + "description": "Get answers with citations using the exa api.", + "mockTool": false, + "parameters": { + "type": "object", + "properties": { + "content": { + "description": "The user message content for the Exa answer API.", + "examples": [ + "give me image of narendra modi" + ], + "title": "Content", + "type": "string" + } + }, + "required": [ + "content" + ] + }, + "isComposio": true, + "composioData": { + "slug": "COMPOSIO_SEARCH_EXA_ANSWER", + "noAuth": true, + "toolkitName": "composio_search", + "toolkitSlug": "composio_search", + "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master//composio-logo.png" + } + }, + { + "name": "Send Email", + "description": "Sends an email via gmail api using the authenticated user's google profile display name, requiring `is html=true` if the body contains html and valid `s3key`, `mimetype`, `name` for any attachment.", + "mockTool": false, + "parameters": { + "type": "object", + "properties": { + "attachment": { + "additionalProperties": false, + "description": "File to attach; ensure `s3key`, `mimetype`, and `name` are set if provided. Omit or set to null for no attachment.", + "file_uploadable": true, + "properties": { + "mimetype": { + "title": "Mimetype", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "s3key": { + "title": "S3Key", + "type": "string" + } + }, + "required": [ + "name", + "mimetype", + "s3key" + ], + "title": "FileUploadable", + "type": "object" + }, + "bcc": { + "default": [], + "description": "Blind Carbon Copy (BCC) recipients' email addresses.", + "examples": [ + [ + "auditor@example.com" + ] + ], + "items": { + "properties": {}, + "type": "string" + }, + "title": "Bcc", + "type": "array" + }, + "body": { + "description": "Email content (plain text or HTML); if HTML, `is_html` must be `True`.", + "examples": [ + "Hello team, let's discuss the project updates tomorrow.", + "

Welcome!

Thank you for signing up.

" + ], + "title": "Body", + "type": "string" + }, + "cc": { + "default": [], + "description": "Carbon Copy (CC) recipients' email addresses.", + "examples": [ + [ + "manager@example.com", + "teamlead@example.com" + ] + ], + "items": { + "properties": {}, + "type": "string" + }, + "title": "Cc", + "type": "array" + }, + "extra_recipients": { + "default": [], + "description": "Additional 'To' recipients' email addresses (not Cc or Bcc).", + "examples": [ + [ + "jane.doe@example.com", + "support@example.com" + ] + ], + "items": { + "properties": {}, + "type": "string" + }, + "title": "Extra Recipients", + "type": "array" + }, + "is_html": { + "default": false, + "description": "Set to `True` if the email body contains HTML tags.", + "title": "Is Html", + "type": "boolean" + }, + "recipient_email": { + "description": "Primary recipient's email address.", + "examples": [ + "john@doe.com" + ], + "title": "Recipient Email", + "type": "string" + }, + "subject": { + "default": null, + "description": "Subject line of the email.", + "examples": [ + "Project Update Meeting", + "Your Weekly Newsletter" + ], + "nullable": true, + "title": "Subject", + "type": "string" + }, + "user_id": { + "default": "me", + "description": "User's email address; the literal 'me' refers to the authenticated user.", + "examples": [ + "user@example.com", + "me" + ], + "title": "User Id", + "type": "string" + } + }, + "required": [ + "recipient_email", + "body" + ] + }, + "isComposio": true, + "composioData": { + "slug": "GMAIL_SEND_EMAIL", + "noAuth": false, + "toolkitName": "gmail", + "toolkitSlug": "gmail", + "logo": "https://cdn.jsdelivr.net/gh/ComposioHQ/open-logos@master/gmail.svg" + } + } + ], + "pipelines": [ + { + "name": "Meeting Prep Pipeline", + "description": "Pipeline that researches meeting guests, compiles a summary, and sends it via email.", + "agents": [ + "Research Guests Agent", + "Compile Email Agent", + "Send Email Agent" + ] + } + ], + "startAgent": "Meeting Prep Pipeline", + "lastUpdatedAt": "2025-09-12T05:56:12.131Z", + "name": "Meeting Prep Assistant", + "description": "Assistant that researches meeting guests, compiles a summary, and sends it via email.", + "category": "Work Productivity" +} \ No newline at end of file diff --git a/apps/rowboat/app/lib/prebuilt-cards/Reddit on Slack.json b/apps/rowboat/app/lib/prebuilt-cards/reddit-on-slack.json similarity index 100% rename from apps/rowboat/app/lib/prebuilt-cards/Reddit on Slack.json rename to apps/rowboat/app/lib/prebuilt-cards/reddit-on-slack.json diff --git a/apps/rowboat/app/lib/prebuilt-cards/Tweet with generated image.json b/apps/rowboat/app/lib/prebuilt-cards/tweet-with-generated-image.json similarity index 100% rename from apps/rowboat/app/lib/prebuilt-cards/Tweet with generated image.json rename to apps/rowboat/app/lib/prebuilt-cards/tweet-with-generated-image.json