mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-16 18:25:17 +02:00
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:
parent
a2c92c7491
commit
5284b10cd4
7 changed files with 156 additions and 32 deletions
|
|
@ -3838,6 +3838,8 @@ function App() {
|
||||||
}
|
}
|
||||||
const composioConnectData = getComposioConnectCardData(item)
|
const composioConnectData = getComposioConnectCardData(item)
|
||||||
if (composioConnectData) {
|
if (composioConnectData) {
|
||||||
|
// Skip rendering if this is a duplicate "already connected" card
|
||||||
|
if (composioConnectData.hidden) return null
|
||||||
return (
|
return (
|
||||||
<ComposioConnectCard
|
<ComposioConnectCard
|
||||||
key={item.id}
|
key={item.id}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import {
|
import {
|
||||||
CheckCircleIcon,
|
CheckCircleIcon,
|
||||||
Link2Icon,
|
Link2Icon,
|
||||||
|
|
@ -28,6 +28,7 @@ export function ComposioConnectCard({
|
||||||
"idle" | "connecting" | "connected" | "error"
|
"idle" | "connecting" | "connected" | "error"
|
||||||
>(alreadyConnected ? "connected" : "idle");
|
>(alreadyConnected ? "connected" : "idle");
|
||||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||||
|
const didFireCallback = useRef(alreadyConnected ?? false);
|
||||||
|
|
||||||
// Listen for composio:didConnect events
|
// Listen for composio:didConnect events
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -38,7 +39,10 @@ export function ComposioConnectCard({
|
||||||
if (event.success) {
|
if (event.success) {
|
||||||
setConnectionState("connected");
|
setConnectionState("connected");
|
||||||
setErrorMessage(null);
|
setErrorMessage(null);
|
||||||
if (!alreadyConnected) onConnected?.(toolkitSlug);
|
if (!didFireCallback.current) {
|
||||||
|
didFireCallback.current = true;
|
||||||
|
onConnected?.(toolkitSlug);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setConnectionState("error");
|
setConnectionState("error");
|
||||||
setErrorMessage(event.error || "Connection failed");
|
setErrorMessage(event.error || "Connection failed");
|
||||||
|
|
@ -46,7 +50,7 @@ export function ComposioConnectCard({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return cleanup;
|
return cleanup;
|
||||||
}, [toolkitSlug, alreadyConnected, onConnected]);
|
}, [toolkitSlug, onConnected]);
|
||||||
|
|
||||||
const handleConnect = useCallback(async () => {
|
const handleConnect = useCallback(async () => {
|
||||||
setConnectionState("connecting");
|
setConnectionState("connecting");
|
||||||
|
|
|
||||||
|
|
@ -344,6 +344,7 @@ export function ChatSidebar({
|
||||||
}
|
}
|
||||||
const composioConnectData = getComposioConnectCardData(item)
|
const composioConnectData = getComposioConnectCardData(item)
|
||||||
if (composioConnectData) {
|
if (composioConnectData) {
|
||||||
|
if (composioConnectData.hidden) return null
|
||||||
return (
|
return (
|
||||||
<ComposioConnectCard
|
<ComposioConnectCard
|
||||||
key={item.id}
|
key={item.id}
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,8 @@ export type ComposioConnectCardData = {
|
||||||
toolkitSlug: string
|
toolkitSlug: string
|
||||||
toolkitDisplayName: string
|
toolkitDisplayName: string
|
||||||
alreadyConnected: boolean
|
alreadyConnected: boolean
|
||||||
|
/** When true, the connect card should not be rendered (toolkit was already connected). */
|
||||||
|
hidden: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -275,6 +277,9 @@ export const getComposioConnectCardData = (tool: ToolCall): ComposioConnectCardD
|
||||||
toolkitSlug,
|
toolkitSlug,
|
||||||
toolkitDisplayName: COMPOSIO_DISPLAY_NAMES[toolkitSlug] || toolkitSlug,
|
toolkitDisplayName: COMPOSIO_DISPLAY_NAMES[toolkitSlug] || toolkitSlug,
|
||||||
alreadyConnected,
|
alreadyConnected,
|
||||||
|
// Don't render a connect card if the toolkit was already connected —
|
||||||
|
// the original card from the first connect call already shows the "Connected" state.
|
||||||
|
hidden: alreadyConnected,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,33 +16,14 @@ async function getComposioToolsPrompt(): Promise<string> {
|
||||||
const connectedToolkits = composioAccountsRepo.getConnectedToolkits();
|
const connectedToolkits = composioAccountsRepo.getConnectedToolkits();
|
||||||
const connectedSection = connectedToolkits.length > 0
|
const connectedSection = connectedToolkits.length > 0
|
||||||
? `**Currently connected:** ${connectedToolkits.map(slug => CURATED_TOOLKITS.find(t => t.slug === slug)?.displayName ?? slug).join(', ')}`
|
? `**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 `
|
return `
|
||||||
## Composio Integrations
|
## Composio Integrations
|
||||||
|
|
||||||
You can connect to external services (Gmail, Slack, GitHub, Notion, etc.) via Composio.
|
|
||||||
|
|
||||||
${connectedSection}
|
${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.
|
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.
|
||||||
|
|
||||||
**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
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,9 +48,9 @@ You're an insightful, encouraging assistant who combines meticulous clarity with
|
||||||
## What Rowboat Is
|
## 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.
|
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.
|
**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.
|
- 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.
|
- 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
|
## Execution Reminders
|
||||||
- Explore existing files and structure before creating new assets.
|
- 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\`.
|
- \`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.**
|
- \`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.
|
- \`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-list-toolkits\`, \`composio-search-tools\`, \`composio-execute-tool\`, \`composio-connect-toolkit\` — Composio integration tools. Load the \`composio-integration\` skill for usage guidance.
|
||||||
- \`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
|
|
||||||
|
|
||||||
**Prefer these tools whenever possible** — they work instantly with zero friction. For file operations inside \`~/.rowboat/\`, always use these instead of \`executeCommand\`.
|
**Prefer these tools whenever possible** — they work instantly with zero friction. For file operations inside \`~/.rowboat/\`, always use these instead of \`executeCommand\`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -12,6 +12,7 @@ import backgroundAgentsSkill from "./background-agents/skill.js";
|
||||||
import createPresentationsSkill from "./create-presentations/skill.js";
|
import createPresentationsSkill from "./create-presentations/skill.js";
|
||||||
|
|
||||||
import appNavigationSkill from "./app-navigation/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 CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const CATALOG_PREFIX = "src/application/assistant/skills";
|
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.",
|
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,
|
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",
|
id: "deletion-guardrails",
|
||||||
title: "Deletion Guardrails",
|
title: "Deletion Guardrails",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue