Enhance Composio connection handling and improve rendering logic

- Added a 'hidden' property to ComposioConnectCardData to prevent rendering of duplicate connection cards.
- Updated App and ChatSidebar components to skip rendering if the card is marked as hidden.
- Refactored ComposioConnectCard to utilize a ref for callback firing, ensuring onConnected is only called once.
- Improved instructions for Composio integration to clarify usage and loading of the composio-integration skill.

This update streamlines the user experience by avoiding duplicate connection prompts and enhances the overall clarity of integration instructions.
This commit is contained in:
tusharmagar 2026-04-03 14:46:32 +05:30
parent a2c92c7491
commit 5284b10cd4
7 changed files with 156 additions and 32 deletions

View file

@ -16,33 +16,14 @@ async function getComposioToolsPrompt(): Promise<string> {
const connectedToolkits = composioAccountsRepo.getConnectedToolkits();
const connectedSection = connectedToolkits.length > 0
? `**Currently connected:** ${connectedToolkits.map(slug => CURATED_TOOLKITS.find(t => t.slug === slug)?.displayName ?? slug).join(', ')}`
: `**No services connected yet.** Use \`composio-list-toolkits\` to show available integrations, or \`composio-connect-toolkit\` to help the user connect one.`;
: `**No services connected yet.** Load the \`composio-integration\` skill to help the user connect one.`;
return `
## Composio Integrations
You can connect to external services (Gmail, Slack, GitHub, Notion, etc.) via Composio.
${connectedSection}
**CRITICAL: NEVER say "I can't access [service]" or "I don't have access to [service]" without FIRST trying Composio.** If a user asks about ANY third-party service (LinkedIn, Gmail, GitHub, Slack, etc.), your FIRST action must be to check \`composio-list-toolkits\` or try \`composio-connect-toolkit\`. Never give up before trying.
**Discovery & Execution Flow:**
1. When the user asks to interact with a service (e.g., "get my LinkedIn profile", "check my email", "list GitHub issues"):
a. Check if the service is connected (via \`composio-list-toolkits\` or the connected list above)
b. If NOT connected, call \`composio-connect-toolkit\` immediately — do NOT ask for confirmation
c. If connected, proceed to search and execute
2. Use \`composio-search-tools\` with SHORT keyword queries (e.g., "list issues", "send email", "get profile") — avoid long sentences.
3. Read the \`inputSchema\` from search results carefully — note which fields are in \`required\`.
4. Call \`composio-execute-tool\` with the tool slug, toolkit slug, AND all required \`arguments\`. For tools with empty \`properties: {}\`, pass \`arguments: {}\`.
**Important:**
- Use short keyword search queries, NOT full sentences (good: "list issues", bad: "get all open issues for a GitHub repository")
- ALWAYS pass required arguments to composio-execute-tool read the inputSchema from search results
- **If a tool call fails, fix the arguments and retry IMMEDIATELY do NOT stop and narrate the error to the user.**
- **Multi-part requests:** When the user asks to "connect X and then do Y", complete BOTH parts. If part 1 (connect) is already done, proceed directly to part 2.
- Confirm with the user before executing tools that send messages, create items, or modify data (NOT for read-only queries or connecting)
- Connecting a toolkit is always safe just do it when needed, don't ask permission
Load the \`composio-integration\` skill when the user asks to interact with any third-party service. NEVER say "I can't access [service]" without loading the skill and trying Composio first.
`;
}
@ -67,9 +48,9 @@ You're an insightful, encouraging assistant who combines meticulous clarity with
## What Rowboat Is
Rowboat is an agentic assistant for everyday work - emails, meetings, projects, and people. Users give you tasks like "draft a follow-up email," "prep me for this meeting," or "summarize where we are with this project." You figure out what context you need, pull from emails and meetings, and get it done.
**Email Drafting:** When users ask you to **draft** or **compose** emails (e.g., "draft a follow-up to Monica", "write an email to John about the project"), load the \`draft-emails\` skill first. Do NOT load this skill for reading, fetching, or checking emails — use Composio tools for that instead.
**Email Drafting:** When users ask you to **draft** or **compose** emails (e.g., "draft a follow-up to Monica", "write an email to John about the project"), load the \`draft-emails\` skill first. Do NOT load this skill for reading, fetching, or checking emails — use the \`composio-integration\` skill for that instead.
**Live Email/Calendar/Service Queries:** When users ask to **read**, **fetch**, **check**, or **view** emails, calendar events, or any data from a connected service (e.g., "what's my latest email?", "check my inbox", "what meetings do I have today?"), use \`composio-search-tools\` and \`composio-execute-tool\` to query the connected service directly. Do NOT look in local \`gmail_sync/\` or \`calendar_sync/\` folders — use Composio for live data.
**Third-Party Services:** When users ask to interact with any external service (Gmail, GitHub, Slack, LinkedIn, Notion, Google Sheets, Jira, etc.) reading emails, listing issues, sending messages, fetching profiles load the \`composio-integration\` skill first. Do NOT look in local \`gmail_sync/\` or \`calendar_sync/\` folders for live data.
**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.
@ -210,9 +191,9 @@ Always consult this catalog first so you load the right skills before taking act
- Never start a response with a heading. Lead with a sentence or two of context first.
- Avoid deeply nested bullets. If nesting beyond 2 levels, restructure.
## Tool Priority: Composio First, Then MCP
## Tool Priority
For third-party services (GitHub, Gmail, Slack, etc.), use \`composio-*\` builtin tools first. Only fall back to MCP tools for capabilities Composio doesn't cover (web search, file scraping, audio). See the dynamic "Composio Integrations" section below for full details.
For third-party services (GitHub, Gmail, Slack, etc.), load the \`composio-integration\` skill. For capabilities Composio doesn't cover (web search, file scraping, audio), use MCP tools via the \`mcp-integration\` skill.
## Execution Reminders
- Explore existing files and structure before creating new assets.
@ -252,10 +233,7 @@ ${runtimeContextPrompt}
- \`web-search\` - Search the web. Returns rich results with full text, highlights, and metadata. The \`category\` parameter defaults to \`general\` (full web search) — only use a specific category like \`news\`, \`company\`, \`research paper\` etc. when the query is clearly about that type. For everyday queries (weather, restaurants, prices, how-to), use \`general\`.
- \`app-navigation\` - Control the app UI: open notes, switch views, filter/search the knowledge base, manage saved views. **Load the \`app-navigation\` skill before using this tool.**
- \`save-to-memory\` - Save observations about the user to the agent memory system. Use this proactively during conversations.
- \`composio-list-toolkits\` — List available integrations (Gmail, Slack, GitHub, etc.) and their connection status
- \`composio-search-tools\` — Search for tools by use case (e.g., "send email", "create issue"); returns tool slugs and input schemas
- \`composio-execute-tool\` — Execute a Composio tool by slug with parameters from search results
- \`composio-connect-toolkit\` — Connect a service (Gmail, Slack, GitHub, etc.) via OAuth directly from chat
- \`composio-list-toolkits\`, \`composio-search-tools\`, \`composio-execute-tool\`, \`composio-connect-toolkit\` — Composio integration tools. Load the \`composio-integration\` skill for usage guidance.
**Prefer these tools whenever possible** they work instantly with zero friction. For file operations inside \`~/.rowboat/\`, always use these instead of \`executeCommand\`.

View file

@ -0,0 +1,127 @@
export const skill = String.raw`
# Composio Integration
**Load this skill** when the user asks to interact with ANY third-party service email, GitHub, Slack, LinkedIn, Notion, Jira, Google Sheets, calendar, etc. This skill provides the complete workflow for discovering, connecting, and executing Composio tools.
## Available Tools
| Tool | Purpose |
|------|---------|
| **composio-list-toolkits** | List all available integrations and their connection status |
| **composio-search-tools** | Search for tools by use case; returns slugs and input schemas |
| **composio-execute-tool** | Execute a tool by slug with parameters |
| **composio-connect-toolkit** | Connect a service via OAuth (opens browser) |
## Toolkit Slugs (exact values for toolkitSlug parameter)
| Service | Slug |
|---------|------|
| Gmail | \`gmail\` |
| Google Calendar | \`googlecalendar\` |
| Google Sheets | \`googlesheets\` |
| Google Docs | \`googledocs\` |
| Google Drive | \`googledrive\` |
| Slack | \`slack\` |
| GitHub | \`github\` |
| Notion | \`notion\` |
| Linear | \`linear\` |
| Jira | \`jira\` |
| Asana | \`asana\` |
| Trello | \`trello\` |
| HubSpot | \`hubspot\` |
| Salesforce | \`salesforce\` |
| LinkedIn | \`linkedin\` |
| X (Twitter) | \`twitter\` |
| Reddit | \`reddit\` |
| Dropbox | \`dropbox\` |
| OneDrive | \`onedrive\` |
| Microsoft Outlook | \`microsoft_outlook\` |
| Microsoft Teams | \`microsoft_teams\` |
| Calendly | \`calendly\` |
| Cal.com | \`cal\` |
| Intercom | \`intercom\` |
| Zendesk | \`zendesk\` |
| Airtable | \`airtable\` |
**IMPORTANT:** Always use these exact slugs. Do NOT guess e.g., Google Sheets is \`googlesheets\` (no underscore), not \`google_sheets\`.
## Critical: Check First, Connect Second
**BEFORE calling composio-connect-toolkit, ALWAYS check if the service is already connected.** The system prompt includes a "Currently connected" list. If the service is there, skip connecting and go straight to search + execute.
**Flow:**
1. Check if the service is in the "Currently connected" list (in the system prompt above)
2. If **connected** go directly to step 4
3. If **NOT connected** call \`composio-connect-toolkit\` once, wait for user to authenticate, then continue
4. Call \`composio-search-tools\` with SHORT keyword queries
5. Read the \`inputSchema\` from results — note \`required\` fields
6. Call \`composio-execute-tool\` with slug, toolkit, and all required arguments
**NEVER call composio-connect-toolkit for a service that's already connected.** This creates duplicate connect cards in the UI.
## Search Query Tips
Use **short keyword queries**, not full sentences:
| Good | Bad |
|---------|--------|
| "list issues" | "get all open issues for a GitHub repository" |
| "send email" | "send an email to someone using Gmail" |
| "get profile" | "fetch the authenticated user's profile details" |
| "create spreadsheet" | "create a new Google Sheets spreadsheet with data" |
If the first search returns 0 results, try a different short query (e.g., "issues" instead of "list issues").
## Passing Arguments
**ALWAYS include the \`arguments\` field** when calling \`composio-execute-tool\`, even if the tool has no required parameters.
- Read the \`inputSchema\` from search results carefully
- Extract user-provided values into the correct fields (e.g., "rowboatlabs/rowboat" \`owner: "rowboatlabs", repo: "rowboat"\`)
- For tools with empty \`properties: {}\`, pass \`arguments: {}\`
- For tools with required fields, pass all of them
### Example: GitHub Issues
User says: "Get me the open issues on rowboatlabs/rowboat"
1. \`composio-search-tools({ query: "list issues", toolkitSlug: "github" })\`
finds \`GITHUB_ISSUES_LIST_FOR_REPO\` with required: ["owner", "repo"]
2. \`composio-execute-tool({ toolSlug: "GITHUB_ISSUES_LIST_FOR_REPO", toolkitSlug: "github", arguments: { owner: "rowboatlabs", repo: "rowboat", state: "open", per_page: 100 } })\`
### Example: Gmail Fetch
User says: "What's my latest email?"
1. \`composio-search-tools({ query: "fetch emails", toolkitSlug: "gmail" })\`
finds \`GMAIL_FETCH_EMAILS\`
2. \`composio-execute-tool({ toolSlug: "GMAIL_FETCH_EMAILS", toolkitSlug: "gmail", arguments: { user_id: "me", max_results: 5 } })\`
### Example: LinkedIn Profile (no-arg tool)
User says: "Get my LinkedIn profile"
1. \`composio-search-tools({ query: "get profile", toolkitSlug: "linkedin" })\`
finds \`LINKEDIN_GET_MY_INFO\` with properties: {}
2. \`composio-execute-tool({ toolSlug: "LINKEDIN_GET_MY_INFO", toolkitSlug: "linkedin", arguments: {} })\`
## Error Recovery
- **If a tool call fails** (missing fields, 500 error): Fix the arguments and retry IMMEDIATELY. Do NOT stop and narrate the error to the user.
- **If search returns 0 results**: Try a different short query. If still 0, the tool may not exist for that service.
- **If a tool requires connection**: Call \`composio-connect-toolkit\` once, then retry after connection.
## Multi-Part Requests
When the user says "connect X and then do Y" complete BOTH parts in one turn:
1. If X is already connected (check the connected list), skip to Y immediately
2. If X needs connecting, connect it, then proceed to Y after authentication
## Confirmation Rules
- **Read-only actions** (fetch, list, get, search): Execute without asking
- **Mutating actions** (send email, create issue, post, delete): Show the user what you're about to do and confirm before executing
- **Connecting a toolkit**: Always safe just do it when needed
`;
export default skill;

View file

@ -12,6 +12,7 @@ import backgroundAgentsSkill from "./background-agents/skill.js";
import createPresentationsSkill from "./create-presentations/skill.js";
import appNavigationSkill from "./app-navigation/skill.js";
import composioIntegrationSkill from "./composio-integration/skill.js";
const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url));
const CATALOG_PREFIX = "src/application/assistant/skills";
@ -84,6 +85,12 @@ const definitions: SkillDefinition[] = [
summary: "Discovering, executing, and integrating MCP tools. Use this to check what external capabilities are available and execute MCP tools on behalf of users.",
content: mcpIntegrationSkill,
},
{
id: "composio-integration",
title: "Composio Integration",
summary: "Interact with third-party services (Gmail, GitHub, Slack, LinkedIn, Notion, Jira, Google Sheets, etc.) via Composio. Search, connect, and execute tools.",
content: composioIntegrationSkill,
},
{
id: "deletion-guardrails",
title: "Deletion Guardrails",