mirror of https://github.com/kortix-ai/suna.git
fix: conditionally display event triggers
This commit is contained in:
parent
01401a1c9f
commit
d791528b56
|
@ -1,4 +1,5 @@
|
|||
import datetime
|
||||
from utils.config import config, EnvMode
|
||||
|
||||
AGENT_BUILDER_SYSTEM_PROMPT = f"""You are an AI Worker Builder Assistant developed by team Suna - think of yourself as a friendly, knowledgeable guide who's genuinely excited to help users create amazing AI Workers! 🚀
|
||||
|
||||
|
@ -58,16 +59,18 @@ Build structured, repeatable processes:
|
|||
- **`activate_workflow`**: Enable/disable workflow execution
|
||||
|
||||
### ⏰ Trigger Management
|
||||
Schedule automatic execution and event-based triggers:
|
||||
Schedule automatic execution{f''' and event-based triggers''' if config.ENV_MODE != EnvMode.PRODUCTION else ""}:
|
||||
- **`create_scheduled_trigger`**: Set up cron-based scheduling
|
||||
- **`get_scheduled_triggers`**: View all scheduled tasks
|
||||
- **`delete_scheduled_trigger`**: Remove scheduled tasks
|
||||
- **`toggle_scheduled_trigger`**: Enable/disable scheduled execution
|
||||
\nEvent-based triggers (Composio):
|
||||
{f'''
|
||||
Event-based triggers (Composio):
|
||||
- **`list_event_trigger_apps`**: Discover apps with available event triggers
|
||||
- **`list_app_event_triggers`**: List triggers for a specific app (includes config schema)
|
||||
- **`list_event_profiles`**: List connected profiles to get `profile_id` and `connected_account_id`
|
||||
- **`create_event_trigger`**: Create an event trigger by passing `slug`, `profile_id`, `connected_account_id`, `trigger_config`, and route (`agent` or `workflow`). If route is `agent`, pass `agent_prompt`; if `workflow`, pass `workflow_id` (and optional `workflow_input`).
|
||||
''' if config.ENV_MODE != EnvMode.PRODUCTION else ""}
|
||||
|
||||
### 📊 Agent Management
|
||||
- **`get_current_agent_config`**: Review current setup and capabilities
|
||||
|
|
|
@ -4,6 +4,7 @@ from agentpress.tool import ToolResult, openapi_schema, usage_example
|
|||
from agentpress.thread_manager import ThreadManager
|
||||
from .base_tool import AgentBuilderBaseTool
|
||||
from utils.logger import logger
|
||||
from utils.config import config, EnvMode
|
||||
from datetime import datetime
|
||||
from services.supabase import DBConnection
|
||||
from triggers import get_trigger_service
|
||||
|
@ -17,130 +18,7 @@ class TriggerTool(AgentBuilderBaseTool):
|
|||
def __init__(self, thread_manager: ThreadManager, db_connection, agent_id: str):
|
||||
super().__init__(thread_manager, db_connection, agent_id)
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_event_trigger_apps",
|
||||
"description": "List apps (toolkits) that have available event-based triggers via Composio. Returns slug, name, and logo.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
})
|
||||
@usage_example('''
|
||||
<function_calls>
|
||||
<invoke name="list_event_trigger_apps"></invoke>
|
||||
</function_calls>
|
||||
''')
|
||||
async def list_event_trigger_apps(self) -> ToolResult:
|
||||
try:
|
||||
trigger_service = ComposioTriggerService()
|
||||
response = await trigger_service.list_apps_with_triggers()
|
||||
|
||||
# Return exact same format as API
|
||||
return self.success_response({
|
||||
"message": f"Found {response['total']} apps with triggers",
|
||||
"items": response["items"],
|
||||
"total": response["total"]
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error listing event trigger apps: {e}")
|
||||
return self.fail_response(f"Error listing apps: {str(e)}")
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_app_event_triggers",
|
||||
"description": "List available triggers for a given app/toolkit slug. Includes slug, name, description, type, instructions, config, and payload schema.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"toolkit_slug": {
|
||||
"type": "string",
|
||||
"description": "Toolkit slug, e.g. 'gmail'"
|
||||
}
|
||||
},
|
||||
"required": ["toolkit_slug"]
|
||||
}
|
||||
}
|
||||
})
|
||||
@usage_example('''
|
||||
<function_calls>
|
||||
<invoke name="list_app_event_triggers">
|
||||
<parameter name="toolkit_slug">gmail</parameter>
|
||||
</invoke>
|
||||
</function_calls>
|
||||
''')
|
||||
async def list_app_event_triggers(self, toolkit_slug: str) -> ToolResult:
|
||||
try:
|
||||
trigger_service = ComposioTriggerService()
|
||||
response = await trigger_service.list_triggers_for_app(toolkit_slug)
|
||||
|
||||
# Return exact same format as API
|
||||
return self.success_response({
|
||||
"message": f"Found {response['total']} triggers for {toolkit_slug}",
|
||||
"items": response["items"],
|
||||
"toolkit": response["toolkit"],
|
||||
"total": response["total"]
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error listing triggers for app {toolkit_slug}: {e}")
|
||||
return self.fail_response(f"Error listing triggers: {str(e)}")
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_event_profiles",
|
||||
"description": "List connected Composio profiles for a toolkit. Use this to get profile_id and connected_account_id before creating a trigger.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"toolkit_slug": {
|
||||
"type": "string",
|
||||
"description": "Toolkit slug, e.g. 'gmail'"
|
||||
}
|
||||
},
|
||||
"required": ["toolkit_slug"]
|
||||
}
|
||||
}
|
||||
})
|
||||
@usage_example('''
|
||||
<function_calls>
|
||||
<invoke name="list_event_profiles">
|
||||
<parameter name="toolkit_slug">gmail</parameter>
|
||||
</invoke>
|
||||
</function_calls>
|
||||
''')
|
||||
async def list_event_profiles(self, toolkit_slug: str) -> ToolResult:
|
||||
try:
|
||||
client = await self.db.client
|
||||
agent_rows = await client.table('agents').select('account_id').eq('agent_id', self.agent_id).execute()
|
||||
if not agent_rows.data:
|
||||
return self.fail_response("Agent not found")
|
||||
account_id = agent_rows.data[0]['account_id']
|
||||
|
||||
profile_service = ComposioProfileService(self.db)
|
||||
profiles = await profile_service.get_profiles(account_id, toolkit_slug)
|
||||
|
||||
items = []
|
||||
for p in profiles:
|
||||
items.append({
|
||||
"profile_id": p.profile_id,
|
||||
"display_name": p.display_name,
|
||||
"is_connected": p.is_connected,
|
||||
"connected_account_id": getattr(p, 'connected_account_id', None)
|
||||
})
|
||||
|
||||
return self.success_response({
|
||||
"message": f"Found {len(items)} profile(s) for {toolkit_slug}",
|
||||
"items": items,
|
||||
"total": len(items)
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error listing event profiles: {e}")
|
||||
return self.fail_response(f"Error listing profiles: {str(e)}")
|
||||
# ===== SCHEDULED TRIGGERS =====
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
|
@ -474,6 +352,142 @@ class TriggerTool(AgentBuilderBaseTool):
|
|||
logger.error(f"Error toggling scheduled trigger: {str(e)}")
|
||||
return self.fail_response(f"Error toggling scheduled trigger: {str(e)}")
|
||||
|
||||
# ===== EVENT-BASED TRIGGERS (Non-Production Only) =====
|
||||
|
||||
# Event trigger methods - only available in non-production environments
|
||||
if config.ENV_MODE != EnvMode.PRODUCTION:
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_event_trigger_apps",
|
||||
"description": "List apps (toolkits) that have available event-based triggers via Composio. Returns slug, name, and logo.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": []
|
||||
}
|
||||
}
|
||||
})
|
||||
@usage_example('''
|
||||
<function_calls>
|
||||
<invoke name="list_event_trigger_apps"></invoke>
|
||||
</function_calls>
|
||||
''')
|
||||
async def list_event_trigger_apps(self) -> ToolResult:
|
||||
try:
|
||||
trigger_service = ComposioTriggerService()
|
||||
response = await trigger_service.list_apps_with_triggers()
|
||||
|
||||
# Return exact same format as API
|
||||
return self.success_response({
|
||||
"message": f"Found {response['total']} apps with triggers",
|
||||
"items": response["items"],
|
||||
"total": response["total"]
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error listing event trigger apps: {e}")
|
||||
return self.fail_response(f"Error listing apps: {str(e)}")
|
||||
|
||||
TriggerTool.list_event_trigger_apps = list_event_trigger_apps
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_app_event_triggers",
|
||||
"description": "List available triggers for a given app/toolkit slug. Includes slug, name, description, type, instructions, config, and payload schema.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"toolkit_slug": {
|
||||
"type": "string",
|
||||
"description": "Toolkit slug, e.g. 'gmail'"
|
||||
}
|
||||
},
|
||||
"required": ["toolkit_slug"]
|
||||
}
|
||||
}
|
||||
})
|
||||
@usage_example('''
|
||||
<function_calls>
|
||||
<invoke name="list_app_event_triggers">
|
||||
<parameter name="toolkit_slug">gmail</parameter>
|
||||
</invoke>
|
||||
</function_calls>
|
||||
''')
|
||||
async def list_app_event_triggers(self, toolkit_slug: str) -> ToolResult:
|
||||
try:
|
||||
trigger_service = ComposioTriggerService()
|
||||
response = await trigger_service.list_triggers_for_app(toolkit_slug)
|
||||
|
||||
# Return exact same format as API
|
||||
return self.success_response({
|
||||
"message": f"Found {response['total']} triggers for {toolkit_slug}",
|
||||
"items": response["items"],
|
||||
"toolkit": response["toolkit"],
|
||||
"total": response["total"]
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error listing triggers for app {toolkit_slug}: {e}")
|
||||
return self.fail_response(f"Error listing triggers: {str(e)}")
|
||||
|
||||
TriggerTool.list_app_event_triggers = list_app_event_triggers
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_event_profiles",
|
||||
"description": "List connected Composio profiles for a toolkit. Use this to get profile_id and connected_account_id before creating a trigger.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"toolkit_slug": {
|
||||
"type": "string",
|
||||
"description": "Toolkit slug, e.g. 'gmail'"
|
||||
}
|
||||
},
|
||||
"required": ["toolkit_slug"]
|
||||
}
|
||||
}
|
||||
})
|
||||
@usage_example('''
|
||||
<function_calls>
|
||||
<invoke name="list_event_profiles">
|
||||
<parameter name="toolkit_slug">gmail</parameter>
|
||||
</invoke>
|
||||
</function_calls>
|
||||
''')
|
||||
async def list_event_profiles(self, toolkit_slug: str) -> ToolResult:
|
||||
try:
|
||||
client = await self.db.client
|
||||
agent_rows = await client.table('agents').select('account_id').eq('agent_id', self.agent_id).execute()
|
||||
if not agent_rows.data:
|
||||
return self.fail_response("Agent not found")
|
||||
account_id = agent_rows.data[0]['account_id']
|
||||
|
||||
profile_service = ComposioProfileService(self.db)
|
||||
profiles = await profile_service.get_profiles(account_id, toolkit_slug)
|
||||
|
||||
items = []
|
||||
for p in profiles:
|
||||
items.append({
|
||||
"profile_id": p.profile_id,
|
||||
"display_name": p.display_name,
|
||||
"is_connected": p.is_connected,
|
||||
"connected_account_id": getattr(p, 'connected_account_id', None)
|
||||
})
|
||||
|
||||
return self.success_response({
|
||||
"message": f"Found {len(items)} profile(s) for {toolkit_slug}",
|
||||
"items": items,
|
||||
"total": len(items)
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error listing event profiles: {e}")
|
||||
return self.fail_response(f"Error listing profiles: {str(e)}")
|
||||
|
||||
TriggerTool.list_event_profiles = list_event_profiles
|
||||
|
||||
@openapi_schema({
|
||||
"type": "function",
|
||||
"function": {
|
||||
|
@ -712,3 +726,5 @@ class TriggerTool(AgentBuilderBaseTool):
|
|||
except Exception as e:
|
||||
logger.error(f"Error creating event trigger: {e}", exc_info=True)
|
||||
return self.fail_response(f"Error creating event trigger: {str(e)}")
|
||||
|
||||
TriggerTool.create_event_trigger = create_event_trigger
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from '@/hooks/react-query/triggers';
|
||||
import { toast } from 'sonner';
|
||||
import { EventBasedTriggerDialog } from './event-based-trigger-dialog';
|
||||
import { config, EnvMode } from '@/lib/config';
|
||||
|
||||
interface OneClickIntegrationsProps {
|
||||
agentId: string;
|
||||
|
@ -170,14 +171,14 @@ export const OneClickIntegrations: React.FC<OneClickIntegrationsProps> = ({
|
|||
</Button>
|
||||
);
|
||||
})}
|
||||
<Button
|
||||
{config.ENV_MODE !== EnvMode.PRODUCTION && <Button
|
||||
variant="default"
|
||||
size='sm'
|
||||
onClick={() => setShowEventDialog(true)}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<PlugZap className="h-4 w-4" /> Create app-based Trigger
|
||||
</Button>
|
||||
</Button>}
|
||||
</div>
|
||||
<EventBasedTriggerDialog open={showEventDialog} onOpenChange={setShowEventDialog} agentId={agentId} />
|
||||
{configuringSchedule && (
|
||||
|
|
Loading…
Reference in New Issue