mirror of https://github.com/kortix-ai/suna.git
cleanup db
This commit is contained in:
parent
4eabca8dae
commit
e58cadea00
|
@ -25,6 +25,7 @@ from utils.constants import MODEL_NAME_ALIASES
|
|||
from flags.flags import is_enabled
|
||||
|
||||
from .utils import check_for_active_project_agent_run, stop_agent_run as _stop_agent_run
|
||||
from .config_helper import extract_agent_config, build_unified_config, extract_tools_for_agent_run, get_mcp_configs
|
||||
|
||||
# Initialize shared resources
|
||||
router = APIRouter()
|
||||
|
@ -174,7 +175,6 @@ async def cleanup():
|
|||
logger.info("Completed cleanup of agent API resources")
|
||||
|
||||
async def get_agent_run_with_access_check(client, agent_run_id: str, user_id: str):
|
||||
"""Get agent run data after verifying user access."""
|
||||
agent_run = await client.table('agent_runs').select('*').eq('id', agent_run_id).execute()
|
||||
if not agent_run.data:
|
||||
raise HTTPException(status_code=404, detail="Agent run not found")
|
||||
|
@ -255,56 +255,27 @@ async def start_agent(
|
|||
effective_agent_id = None
|
||||
else:
|
||||
agent_data = agent_result.data[0]
|
||||
# Use version data if available, otherwise fall back to agent data (for backward compatibility)
|
||||
if agent_data.get('agent_versions'):
|
||||
version_data = agent_data['agent_versions']
|
||||
agent_config = {
|
||||
'agent_id': agent_data['agent_id'],
|
||||
'name': agent_data['name'],
|
||||
'description': agent_data.get('description'),
|
||||
'system_prompt': version_data['system_prompt'],
|
||||
'configured_mcps': version_data.get('configured_mcps', []),
|
||||
'custom_mcps': version_data.get('custom_mcps', []),
|
||||
'agentpress_tools': version_data.get('agentpress_tools', {}),
|
||||
'is_default': agent_data.get('is_default', False),
|
||||
'current_version_id': agent_data.get('current_version_id'),
|
||||
'version_name': version_data.get('version_name', 'v1')
|
||||
}
|
||||
logger.info(f"Using agent {agent_config['name']} ({effective_agent_id}) version {agent_config['version_name']}")
|
||||
version_data = agent_data.get('agent_versions')
|
||||
agent_config = extract_agent_config(agent_data, version_data)
|
||||
|
||||
if version_data:
|
||||
logger.info(f"Using agent {agent_config['name']} ({effective_agent_id}) version {agent_config.get('version_name', 'v1')}")
|
||||
else:
|
||||
# Backward compatibility - use agent data directly
|
||||
agent_config = agent_data
|
||||
logger.info(f"Using agent {agent_config['name']} ({effective_agent_id}) - no version data")
|
||||
source = "request" if body.agent_id else "thread"
|
||||
|
||||
# If no agent found yet, try to get default agent for the account
|
||||
if not agent_config:
|
||||
default_agent_result = await client.table('agents').select('*, agent_versions!current_version_id(*)').eq('account_id', account_id).eq('is_default', True).execute()
|
||||
if default_agent_result.data:
|
||||
agent_data = default_agent_result.data[0]
|
||||
# Use version data if available
|
||||
if agent_data.get('agent_versions'):
|
||||
version_data = agent_data['agent_versions']
|
||||
agent_config = {
|
||||
'agent_id': agent_data['agent_id'],
|
||||
'name': agent_data['name'],
|
||||
'description': agent_data.get('description'),
|
||||
'system_prompt': version_data['system_prompt'],
|
||||
'configured_mcps': version_data.get('configured_mcps', []),
|
||||
'custom_mcps': version_data.get('custom_mcps', []),
|
||||
'agentpress_tools': version_data.get('agentpress_tools', {}),
|
||||
'is_default': agent_data.get('is_default', False),
|
||||
'current_version_id': agent_data.get('current_version_id'),
|
||||
'version_name': version_data.get('version_name', 'v1')
|
||||
}
|
||||
logger.info(f"Using default agent: {agent_config['name']} ({agent_config['agent_id']}) version {agent_config['version_name']}")
|
||||
version_data = agent_data.get('agent_versions')
|
||||
agent_config = extract_agent_config(agent_data, version_data)
|
||||
|
||||
if version_data:
|
||||
logger.info(f"Using default agent: {agent_config['name']} ({agent_config['agent_id']}) version {agent_config.get('version_name', 'v1')}")
|
||||
else:
|
||||
agent_config = agent_data
|
||||
logger.info(f"Using default agent: {agent_config['name']} ({agent_config['agent_id']}) - no version data")
|
||||
|
||||
|
||||
# Don't update thread's agent_id since threads are now agent-agnostic
|
||||
# The agent selection is handled per message/agent run
|
||||
if body.agent_id and body.agent_id != thread_agent_id and agent_config:
|
||||
logger.info(f"Using agent {agent_config['agent_id']} for this agent run (thread remains agent-agnostic)")
|
||||
|
||||
|
@ -1321,11 +1292,23 @@ async def create_agent(
|
|||
if agent_data.is_default:
|
||||
await client.table('agents').update({"is_default": False}).eq("account_id", user_id).eq("is_default", True).execute()
|
||||
|
||||
# Build unified config
|
||||
unified_config = build_unified_config(
|
||||
system_prompt=agent_data.system_prompt,
|
||||
agentpress_tools=agent_data.agentpress_tools or {},
|
||||
configured_mcps=agent_data.configured_mcps or [],
|
||||
custom_mcps=agent_data.custom_mcps or [],
|
||||
avatar=agent_data.avatar,
|
||||
avatar_color=agent_data.avatar_color
|
||||
)
|
||||
|
||||
# Create the agent
|
||||
insert_data = {
|
||||
"account_id": user_id,
|
||||
"name": agent_data.name,
|
||||
"description": agent_data.description,
|
||||
"config": unified_config,
|
||||
# Keep legacy columns for backward compatibility
|
||||
"system_prompt": agent_data.system_prompt,
|
||||
"configured_mcps": agent_data.configured_mcps or [],
|
||||
"custom_mcps": agent_data.custom_mcps or [],
|
||||
|
@ -1348,6 +1331,8 @@ async def create_agent(
|
|||
"agent_id": agent['agent_id'],
|
||||
"version_number": 1,
|
||||
"version_name": "v1",
|
||||
"config": unified_config,
|
||||
# Keep legacy columns for backward compatibility
|
||||
"system_prompt": agent_data.system_prompt,
|
||||
"configured_mcps": agent_data.configured_mcps or [],
|
||||
"custom_mcps": agent_data.custom_mcps or [],
|
||||
|
@ -1364,16 +1349,7 @@ async def create_agent(
|
|||
await client.table('agents').update({
|
||||
"current_version_id": version['version_id']
|
||||
}).eq("agent_id", agent['agent_id']).execute()
|
||||
|
||||
# Add version history entry
|
||||
await client.table('agent_version_history').insert({
|
||||
"agent_id": agent['agent_id'],
|
||||
"version_id": version['version_id'],
|
||||
"action": "created",
|
||||
"changed_by": user_id,
|
||||
"change_description": "Initial version v1 created"
|
||||
}).execute()
|
||||
|
||||
|
||||
agent['current_version_id'] = version['version_id']
|
||||
agent['current_version'] = version
|
||||
|
||||
|
@ -1520,6 +1496,24 @@ async def update_agent(
|
|||
if agent_data.avatar_color is not None:
|
||||
update_data["avatar_color"] = agent_data.avatar_color
|
||||
|
||||
# Build unified config with all current values
|
||||
current_system_prompt = agent_data.system_prompt if agent_data.system_prompt is not None else current_version_data.get('system_prompt', '')
|
||||
current_configured_mcps = agent_data.configured_mcps if agent_data.configured_mcps is not None else current_version_data.get('configured_mcps', [])
|
||||
current_custom_mcps = agent_data.custom_mcps if agent_data.custom_mcps is not None else current_version_data.get('custom_mcps', [])
|
||||
current_agentpress_tools = agent_data.agentpress_tools if agent_data.agentpress_tools is not None else current_version_data.get('agentpress_tools', {})
|
||||
current_avatar = agent_data.avatar if agent_data.avatar is not None else existing_data.get('avatar')
|
||||
current_avatar_color = agent_data.avatar_color if agent_data.avatar_color is not None else existing_data.get('avatar_color')
|
||||
|
||||
unified_config = build_unified_config(
|
||||
system_prompt=current_system_prompt,
|
||||
agentpress_tools=current_agentpress_tools,
|
||||
configured_mcps=current_configured_mcps,
|
||||
custom_mcps=current_custom_mcps,
|
||||
avatar=current_avatar,
|
||||
avatar_color=current_avatar_color
|
||||
)
|
||||
update_data["config"] = unified_config
|
||||
|
||||
# Also update the agent table with the latest values (for backward compatibility)
|
||||
if agent_data.system_prompt is not None:
|
||||
update_data["system_prompt"] = agent_data.system_prompt
|
||||
|
@ -1553,6 +1547,17 @@ async def update_agent(
|
|||
"created_by": user_id
|
||||
}
|
||||
|
||||
# Build unified config for the new version
|
||||
version_unified_config = build_unified_config(
|
||||
system_prompt=new_version_data["system_prompt"],
|
||||
agentpress_tools=new_version_data["agentpress_tools"],
|
||||
configured_mcps=new_version_data["configured_mcps"],
|
||||
custom_mcps=new_version_data["custom_mcps"],
|
||||
avatar=None, # Avatar is not versioned
|
||||
avatar_color=None # Avatar color is not versioned
|
||||
)
|
||||
new_version_data["config"] = version_unified_config
|
||||
|
||||
# Validate system prompt is not empty
|
||||
if not new_version_data["system_prompt"] or new_version_data["system_prompt"].strip() == '':
|
||||
raise HTTPException(status_code=400, detail="System prompt cannot be empty")
|
||||
|
@ -1566,17 +1571,17 @@ async def update_agent(
|
|||
update_data['current_version_id'] = new_version_id
|
||||
update_data['version_count'] = next_version_number
|
||||
|
||||
# Add version history entry
|
||||
try:
|
||||
await client.table('agent_version_history').insert({
|
||||
"agent_id": agent_id,
|
||||
"version_id": new_version_id,
|
||||
"action": "created",
|
||||
"changed_by": user_id,
|
||||
"change_description": f"New version v{next_version_number} created from update"
|
||||
}).execute()
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to create version history entry: {e}")
|
||||
# Don't add version history entry - table was dropped in migration
|
||||
# try:
|
||||
# await client.table('agent_version_history').insert({
|
||||
# "agent_id": agent_id,
|
||||
# "version_id": new_version_id,
|
||||
# "action": "created",
|
||||
# "changed_by": user_id,
|
||||
# "change_description": f"New version v{next_version_number} created from update"
|
||||
# }).execute()
|
||||
# except Exception as e:
|
||||
# logger.warning(f"Failed to create version history entry: {e}")
|
||||
|
||||
logger.info(f"Created new version v{next_version_number} for agent {agent_id}")
|
||||
|
||||
|
@ -1808,6 +1813,17 @@ async def create_agent_version(
|
|||
"created_by": user_id
|
||||
}
|
||||
|
||||
# Build unified config for the new version
|
||||
version_unified_config = build_unified_config(
|
||||
system_prompt=new_version_data["system_prompt"],
|
||||
agentpress_tools=new_version_data["agentpress_tools"],
|
||||
configured_mcps=new_version_data["configured_mcps"],
|
||||
custom_mcps=new_version_data["custom_mcps"],
|
||||
avatar=None, # Avatar is not versioned
|
||||
avatar_color=None # Avatar color is not versioned
|
||||
)
|
||||
new_version_data["config"] = version_unified_config
|
||||
|
||||
new_version = await client.table('agent_versions').insert(new_version_data).execute()
|
||||
|
||||
if not new_version.data:
|
||||
|
@ -1821,14 +1837,14 @@ async def create_agent_version(
|
|||
"version_count": next_version_number
|
||||
}).eq("agent_id", agent_id).execute()
|
||||
|
||||
# Add version history entry
|
||||
await client.table('agent_version_history').insert({
|
||||
"agent_id": agent_id,
|
||||
"version_id": version['version_id'],
|
||||
"action": "created",
|
||||
"changed_by": user_id,
|
||||
"change_description": f"New version v{next_version_number} created"
|
||||
}).execute()
|
||||
# Don't add version history entry - table was dropped in migration
|
||||
# await client.table('agent_version_history').insert({
|
||||
# "agent_id": agent_id,
|
||||
# "version_id": version['version_id'],
|
||||
# "action": "created",
|
||||
# "changed_by": user_id,
|
||||
# "change_description": f"New version v{next_version_number} created"
|
||||
# }).execute()
|
||||
|
||||
logger.info(f"Created version v{next_version_number} for agent {agent_id}")
|
||||
|
||||
|
@ -1858,14 +1874,14 @@ async def activate_agent_version(
|
|||
"current_version_id": version_id
|
||||
}).eq("agent_id", agent_id).execute()
|
||||
|
||||
# Add version history entry
|
||||
await client.table('agent_version_history').insert({
|
||||
"agent_id": agent_id,
|
||||
"version_id": version_id,
|
||||
"action": "activated",
|
||||
"changed_by": user_id,
|
||||
"change_description": f"Switched to version {version_result.data[0]['version_name']}"
|
||||
}).execute()
|
||||
# Don't add version history entry - table was dropped in migration
|
||||
# await client.table('agent_version_history').insert({
|
||||
# "agent_id": agent_id,
|
||||
# "version_id": version_id,
|
||||
# "action": "activated",
|
||||
# "changed_by": user_id,
|
||||
# "change_description": f"Switched to version {version_result.data[0]['version_name']}"
|
||||
# }).execute()
|
||||
|
||||
return {"message": "Version activated successfully"}
|
||||
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
from typing import Dict, Any, Optional, List
|
||||
from utils.logger import logger
|
||||
|
||||
|
||||
def extract_agent_config(agent_data: Dict[str, Any], version_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
||||
if agent_data.get('config') and agent_data['config'] != {}:
|
||||
config = agent_data['config'].copy()
|
||||
if 'tools' not in config:
|
||||
config['tools'] = {
|
||||
'agentpress': {},
|
||||
'mcp': [],
|
||||
'custom_mcp': []
|
||||
}
|
||||
if 'metadata' not in config:
|
||||
config['metadata'] = {}
|
||||
|
||||
config['agent_id'] = agent_data['agent_id']
|
||||
config['name'] = agent_data['name']
|
||||
config['description'] = agent_data.get('description')
|
||||
config['is_default'] = agent_data.get('is_default', False)
|
||||
config['account_id'] = agent_data.get('account_id')
|
||||
config['current_version_id'] = agent_data.get('current_version_id')
|
||||
|
||||
metadata = config.get('metadata', {})
|
||||
config['avatar'] = metadata.get('avatar')
|
||||
config['avatar_color'] = metadata.get('avatar_color')
|
||||
|
||||
config['agentpress_tools'] = extract_tools_for_agent_run(config)
|
||||
|
||||
config['configured_mcps'] = config.get('tools', {}).get('mcp', [])
|
||||
config['custom_mcps'] = config.get('tools', {}).get('custom_mcp', [])
|
||||
|
||||
return config
|
||||
|
||||
if version_data and version_data.get('config') and version_data['config'] != {}:
|
||||
config = version_data['config'].copy()
|
||||
|
||||
config['agent_id'] = agent_data['agent_id']
|
||||
config['name'] = agent_data['name']
|
||||
config['description'] = agent_data.get('description')
|
||||
config['is_default'] = agent_data.get('is_default', False)
|
||||
config['account_id'] = agent_data.get('account_id')
|
||||
config['current_version_id'] = agent_data.get('current_version_id')
|
||||
config['version_name'] = version_data.get('version_name', 'v1')
|
||||
|
||||
metadata = config.get('metadata', {})
|
||||
config['avatar'] = metadata.get('avatar', agent_data.get('avatar'))
|
||||
config['avatar_color'] = metadata.get('avatar_color', agent_data.get('avatar_color'))
|
||||
|
||||
# Convert agentpress tools to legacy format for run_agent
|
||||
config['agentpress_tools'] = extract_tools_for_agent_run(config)
|
||||
|
||||
# Also extract MCP configs
|
||||
config['configured_mcps'] = config.get('tools', {}).get('mcp', [])
|
||||
config['custom_mcps'] = config.get('tools', {}).get('custom_mcp', [])
|
||||
|
||||
return config
|
||||
|
||||
logger.info(f"Building config from legacy columns for agent {agent_data.get('agent_id')}")
|
||||
source_data = version_data if version_data else agent_data
|
||||
|
||||
legacy_tools = source_data.get('agentpress_tools', {})
|
||||
simplified_tools = {}
|
||||
|
||||
for tool_name, tool_config in legacy_tools.items():
|
||||
if isinstance(tool_config, dict):
|
||||
simplified_tools[tool_name] = tool_config.get('enabled', False)
|
||||
elif isinstance(tool_config, bool):
|
||||
simplified_tools[tool_name] = tool_config
|
||||
|
||||
config = {
|
||||
'agent_id': agent_data['agent_id'],
|
||||
'name': agent_data['name'],
|
||||
'description': agent_data.get('description'),
|
||||
'system_prompt': source_data.get('system_prompt', ''),
|
||||
'tools': {
|
||||
'agentpress': simplified_tools,
|
||||
'mcp': source_data.get('configured_mcps', []),
|
||||
'custom_mcp': source_data.get('custom_mcps', [])
|
||||
},
|
||||
'metadata': {
|
||||
'avatar': agent_data.get('avatar'),
|
||||
'avatar_color': agent_data.get('avatar_color')
|
||||
},
|
||||
'is_default': agent_data.get('is_default', False),
|
||||
'account_id': agent_data.get('account_id'),
|
||||
'current_version_id': agent_data.get('current_version_id'),
|
||||
'avatar': agent_data.get('avatar'),
|
||||
'avatar_color': agent_data.get('avatar_color')
|
||||
}
|
||||
|
||||
if version_data:
|
||||
config['version_name'] = version_data.get('version_name', 'v1')
|
||||
|
||||
config['configured_mcps'] = source_data.get('configured_mcps', [])
|
||||
config['custom_mcps'] = source_data.get('custom_mcps', [])
|
||||
config['agentpress_tools'] = legacy_tools
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def build_unified_config(
|
||||
system_prompt: str,
|
||||
agentpress_tools: Dict[str, Any],
|
||||
configured_mcps: List[Dict[str, Any]],
|
||||
custom_mcps: Optional[List[Dict[str, Any]]] = None,
|
||||
avatar: Optional[str] = None,
|
||||
avatar_color: Optional[str] = None
|
||||
) -> Dict[str, Any]:
|
||||
simplified_tools = {}
|
||||
for tool_name, tool_config in agentpress_tools.items():
|
||||
if isinstance(tool_config, dict):
|
||||
simplified_tools[tool_name] = tool_config.get('enabled', False)
|
||||
elif isinstance(tool_config, bool):
|
||||
simplified_tools[tool_name] = tool_config
|
||||
return {
|
||||
'system_prompt': system_prompt,
|
||||
'tools': {
|
||||
'agentpress': simplified_tools,
|
||||
'mcp': configured_mcps or [],
|
||||
'custom_mcp': custom_mcps or []
|
||||
},
|
||||
'metadata': {
|
||||
'avatar': avatar,
|
||||
'avatar_color': avatar_color
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def extract_tools_for_agent_run(config: Dict[str, Any]) -> Dict[str, Any]:
|
||||
tools = config.get('tools', {})
|
||||
agentpress = tools.get('agentpress', {})
|
||||
|
||||
legacy_format = {}
|
||||
|
||||
for tool_name, enabled in agentpress.items():
|
||||
if isinstance(enabled, bool):
|
||||
legacy_format[tool_name] = {
|
||||
'enabled': enabled,
|
||||
'description': ''
|
||||
}
|
||||
elif isinstance(enabled, dict):
|
||||
legacy_format[tool_name] = enabled
|
||||
|
||||
return legacy_format
|
||||
|
||||
|
||||
def get_mcp_configs(config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
tools = config.get('tools', {})
|
||||
all_mcps = []
|
||||
mcp_list = tools.get('mcp', [])
|
||||
if mcp_list:
|
||||
all_mcps.extend(mcp_list)
|
||||
|
||||
custom_mcp_list = tools.get('custom_mcp', [])
|
||||
if custom_mcp_list:
|
||||
all_mcps.extend(custom_mcp_list)
|
||||
|
||||
if 'configured_mcps' in config:
|
||||
all_mcps.extend(config['configured_mcps'])
|
||||
|
||||
if 'custom_mcps' in config:
|
||||
all_mcps.extend(config['custom_mcps'])
|
||||
|
||||
return all_mcps
|
|
@ -24,6 +24,7 @@ from run_agent_background import run_agent_background, _cleanup_redis_response_l
|
|||
from utils.constants import MODEL_NAME_ALIASES
|
||||
from flags.flags import is_enabled
|
||||
from .utils import check_for_active_project_agent_run, stop_agent_run as _stop_agent_run
|
||||
from .config_helper import extract_agent_config
|
||||
|
||||
router = APIRouter()
|
||||
db = None
|
||||
|
@ -456,24 +457,12 @@ async def execute_agent_workflow(
|
|||
agent_data = agent_result.data[0]
|
||||
account_id = agent_data['account_id']
|
||||
|
||||
if agent_data.get('agent_versions'):
|
||||
version_data = agent_data['agent_versions']
|
||||
agent_config = {
|
||||
'agent_id': agent_data['agent_id'],
|
||||
'name': agent_data['name'],
|
||||
'description': agent_data.get('description'),
|
||||
'system_prompt': version_data['system_prompt'],
|
||||
'configured_mcps': version_data.get('configured_mcps', []),
|
||||
'custom_mcps': version_data.get('custom_mcps', []),
|
||||
'agentpress_tools': version_data.get('agentpress_tools', {}),
|
||||
'is_default': agent_data.get('is_default', False),
|
||||
'current_version_id': agent_data.get('current_version_id'),
|
||||
'version_name': version_data.get('version_name', 'v1')
|
||||
}
|
||||
logger.info(f"Using agent {agent_config['name']} ({agent_id}) version {agent_config['version_name']} for workflow")
|
||||
version_data = agent_data.get('agent_versions')
|
||||
agent_config = extract_agent_config(agent_data, version_data)
|
||||
if version_data:
|
||||
logger.info(f"Using agent {agent_config['name']} ({agent_id}) version {agent_config.get('version_name', 'v1')} for workflow")
|
||||
else:
|
||||
agent_config = agent_data
|
||||
logger.info(f"Using agent {agent_config['name']} ({agent_id}) - no version data")
|
||||
logger.info(f"Using agent {agent_config['name']} ({agent_id}) - no version data for workflow")
|
||||
|
||||
available_tools = []
|
||||
|
||||
|
@ -814,23 +803,9 @@ async def trigger_workflow_webhook(
|
|||
agent_data = agent_result.data[0]
|
||||
account_id = agent_data['account_id']
|
||||
|
||||
if agent_data.get('agent_versions'):
|
||||
version_data = agent_data['agent_versions']
|
||||
agent_config = {
|
||||
'agent_id': agent_data['agent_id'],
|
||||
'name': agent_data['name'],
|
||||
'description': agent_data.get('description'),
|
||||
'system_prompt': version_data['system_prompt'],
|
||||
'configured_mcps': version_data.get('configured_mcps', []),
|
||||
'custom_mcps': version_data.get('custom_mcps', []),
|
||||
'agentpress_tools': version_data.get('agentpress_tools', {}),
|
||||
'is_default': agent_data.get('is_default', False),
|
||||
'current_version_id': agent_data.get('current_version_id'),
|
||||
'version_name': version_data.get('version_name', 'v1'),
|
||||
'account_id': account_id
|
||||
}
|
||||
else:
|
||||
agent_config = {**agent_data, 'account_id': account_id}
|
||||
version_data = agent_data.get('agent_versions')
|
||||
agent_config = extract_agent_config(agent_data, version_data)
|
||||
agent_config['account_id'] = account_id # Ensure account_id is in the config
|
||||
|
||||
from triggers.integration import WorkflowTriggerExecutor
|
||||
from triggers.core import TriggerResult, TriggerEvent, TriggerType
|
||||
|
|
|
@ -414,14 +414,6 @@ class TemplateManager:
|
|||
'current_version_id': version_id,
|
||||
'version_count': 1
|
||||
}).eq('agent_id', instance_id).execute()
|
||||
await client.table('agent_version_history').insert({
|
||||
"agent_id": instance_id,
|
||||
"version_id": version_id,
|
||||
"action": "created",
|
||||
"changed_by": account_id,
|
||||
"change_description": "Initial version created from template installation"
|
||||
}).execute()
|
||||
|
||||
logger.info(f"Created initial version v1 for installed agent {instance_id}")
|
||||
else:
|
||||
logger.warning(f"Failed to create initial version for agent {instance_id}")
|
||||
|
|
|
@ -0,0 +1,236 @@
|
|||
-- =====================================================
|
||||
-- DATABASE CLEANUP MIGRATION
|
||||
-- =====================================================
|
||||
-- This migration:
|
||||
-- 1. Removes unused OLD workflow tables (workflows, workflow_variables, workflow_templates, workflow_flows, workflow_execution_logs)
|
||||
-- 2. Removes webhook_registrations (not used anywhere)
|
||||
-- 3. Removes scheduled_jobs (part of old workflow system)
|
||||
-- 4. Removes agent_instances (using agent_templates + user credentials instead)
|
||||
-- 5. Removes user_mcp_credentials (replaced by user_mcp_credential_profiles)
|
||||
-- 6. Consolidates agent configuration into single JSONB config column
|
||||
-- 7. Comments out oauth_installations (not removed, just renamed to indicate deprecated)
|
||||
-- 8. Consolidates agent_version_history into agent_versions table
|
||||
-- =====================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- =====================================================
|
||||
-- 1. DROP OLD WORKFLOW SYSTEM TABLES
|
||||
-- =====================================================
|
||||
-- These are the old workflow tables from April 2025, NOT the new agent_workflows from July 2025
|
||||
-- Note: workflow_executions is used by BOTH systems, so we don't drop it
|
||||
DROP TABLE IF EXISTS workflow_flows CASCADE;
|
||||
DROP TABLE IF EXISTS workflow_execution_logs CASCADE;
|
||||
DROP TABLE IF EXISTS workflow_variables CASCADE;
|
||||
DROP TABLE IF EXISTS webhook_registrations CASCADE;
|
||||
DROP TABLE IF EXISTS scheduled_jobs CASCADE;
|
||||
DROP TABLE IF EXISTS triggers CASCADE;
|
||||
-- DO NOT DROP workflow_executions - it's used by agent_workflows system
|
||||
DROP TABLE IF EXISTS workflow_templates CASCADE;
|
||||
DROP TABLE IF EXISTS workflows CASCADE;
|
||||
|
||||
-- Drop old workflow types (being careful not to drop types used by agent workflows)
|
||||
DROP TYPE IF EXISTS connection_type CASCADE;
|
||||
DROP TYPE IF EXISTS node_type CASCADE;
|
||||
DROP TYPE IF EXISTS trigger_type CASCADE;
|
||||
DROP TYPE IF EXISTS execution_status CASCADE;
|
||||
DROP TYPE IF EXISTS workflow_status CASCADE;
|
||||
-- DO NOT DROP workflow_execution_status - it's used by agent_workflows system
|
||||
|
||||
-- =====================================================
|
||||
-- 2. REMOVE AGENT_INSTANCES TABLE
|
||||
-- =====================================================
|
||||
-- This table is not used - we have agent_templates for marketplace
|
||||
-- and agents table for user's actual agents
|
||||
DROP TABLE IF EXISTS agent_instances CASCADE;
|
||||
|
||||
-- =====================================================
|
||||
-- 3. REMOVE USER_MCP_CREDENTIALS TABLE
|
||||
-- =====================================================
|
||||
-- This is replaced by user_mcp_credential_profiles
|
||||
DROP TABLE IF EXISTS user_mcp_credentials CASCADE;
|
||||
|
||||
-- =====================================================
|
||||
-- 4. CONSOLIDATE AGENT CONFIGURATION
|
||||
-- =====================================================
|
||||
-- Add new unified config column to agents table
|
||||
ALTER TABLE agents ADD COLUMN IF NOT EXISTS config JSONB DEFAULT '{}'::jsonb;
|
||||
|
||||
-- Migrate existing data to unified config
|
||||
-- Note: agentpress_tools currently stores {tool_name: {enabled: bool, description: string}}
|
||||
-- The description is redundant as it's the same for all agents. In the new structure,
|
||||
-- we'll just store {tool_name: boolean} for enabled/disabled state
|
||||
UPDATE agents
|
||||
SET config = jsonb_build_object(
|
||||
'system_prompt', COALESCE(system_prompt, ''),
|
||||
'tools', jsonb_build_object(
|
||||
'agentpress', (
|
||||
SELECT jsonb_object_agg(
|
||||
key,
|
||||
(value->>'enabled')::boolean
|
||||
)
|
||||
FROM jsonb_each(COALESCE(agentpress_tools, '{}'::jsonb))
|
||||
WHERE value IS NOT NULL AND value != 'null'::jsonb
|
||||
),
|
||||
'mcp', COALESCE(configured_mcps, '[]'::jsonb),
|
||||
'custom_mcp', COALESCE(custom_mcps, '[]'::jsonb)
|
||||
),
|
||||
'metadata', jsonb_build_object(
|
||||
'avatar', avatar,
|
||||
'avatar_color', avatar_color
|
||||
)
|
||||
)
|
||||
WHERE config = '{}'::jsonb OR config IS NULL;
|
||||
|
||||
-- Update agent_versions table to use unified config
|
||||
ALTER TABLE agent_versions ADD COLUMN IF NOT EXISTS config JSONB DEFAULT '{}'::jsonb;
|
||||
|
||||
UPDATE agent_versions
|
||||
SET config = jsonb_build_object(
|
||||
'system_prompt', COALESCE(system_prompt, ''),
|
||||
'tools', jsonb_build_object(
|
||||
'agentpress', (
|
||||
SELECT jsonb_object_agg(
|
||||
key,
|
||||
(value->>'enabled')::boolean
|
||||
)
|
||||
FROM jsonb_each(COALESCE(agentpress_tools, '{}'::jsonb))
|
||||
WHERE value IS NOT NULL AND value != 'null'::jsonb
|
||||
),
|
||||
'mcp', COALESCE(configured_mcps, '[]'::jsonb),
|
||||
'custom_mcp', COALESCE(custom_mcps, '[]'::jsonb)
|
||||
)
|
||||
)
|
||||
WHERE config = '{}'::jsonb OR config IS NULL;
|
||||
|
||||
-- =====================================================
|
||||
-- 5. CONSOLIDATE AGENT_VERSION_HISTORY INTO AGENT_VERSIONS
|
||||
-- =====================================================
|
||||
-- Add history fields to agent_versions
|
||||
ALTER TABLE agent_versions ADD COLUMN IF NOT EXISTS change_description TEXT;
|
||||
ALTER TABLE agent_versions ADD COLUMN IF NOT EXISTS previous_version_id UUID REFERENCES agent_versions(version_id);
|
||||
|
||||
-- Migrate history data
|
||||
UPDATE agent_versions v
|
||||
SET change_description = (
|
||||
SELECT h.change_description
|
||||
FROM agent_version_history h
|
||||
WHERE h.version_id = v.version_id
|
||||
AND h.action = 'created'
|
||||
LIMIT 1
|
||||
);
|
||||
|
||||
-- Drop the separate history table
|
||||
DROP TABLE IF EXISTS agent_version_history CASCADE;
|
||||
|
||||
-- =====================================================
|
||||
-- 6. CLEAN UP USER_AGENT_LIBRARY
|
||||
-- =====================================================
|
||||
-- This table tracks which marketplace agents users have imported
|
||||
-- Add a comment to clarify its purpose
|
||||
COMMENT ON TABLE user_agent_library IS 'Tracks which marketplace agent templates users have imported/cloned to their library';
|
||||
COMMENT ON COLUMN user_agent_library.original_agent_id IS 'The original marketplace agent that was cloned';
|
||||
COMMENT ON COLUMN user_agent_library.agent_id IS 'The user''s cloned copy of the agent';
|
||||
|
||||
-- =====================================================
|
||||
-- 7. COMMENT OUT OAUTH_INSTALLATIONS
|
||||
-- =====================================================
|
||||
-- As requested, comment out OAuth installations functionality
|
||||
-- We'll rename the table to indicate it's deprecated
|
||||
ALTER TABLE IF EXISTS oauth_installations RENAME TO _deprecated_oauth_installations;
|
||||
COMMENT ON TABLE _deprecated_oauth_installations IS 'DEPRECATED: OAuth installations table - functionality has been commented out';
|
||||
|
||||
-- =====================================================
|
||||
-- 8. UPDATE AGENT TRIGGERS TO WORK WITH AGENT_WORKFLOWS
|
||||
-- =====================================================
|
||||
-- Add workflow execution capability to triggers
|
||||
ALTER TABLE agent_triggers ADD COLUMN IF NOT EXISTS execution_type VARCHAR(50) DEFAULT 'agent' CHECK (execution_type IN ('agent', 'workflow'));
|
||||
ALTER TABLE agent_triggers ADD COLUMN IF NOT EXISTS workflow_id UUID REFERENCES agent_workflows(id) ON DELETE SET NULL;
|
||||
|
||||
-- Update trigger_events to track workflow executions
|
||||
-- Note: workflow_executions table exists from agent_workflows system
|
||||
ALTER TABLE trigger_events ADD COLUMN IF NOT EXISTS workflow_execution_id UUID REFERENCES workflow_executions(id) ON DELETE SET NULL;
|
||||
|
||||
-- =====================================================
|
||||
-- 9. CLEAN UP COLUMNS AFTER MIGRATION
|
||||
-- =====================================================
|
||||
-- Schedule these to be dropped in a future migration after code is updated
|
||||
COMMENT ON COLUMN agents.system_prompt IS 'DEPRECATED: Use config->>system_prompt instead';
|
||||
COMMENT ON COLUMN agents.configured_mcps IS 'DEPRECATED: Use config->>tools->>mcp instead';
|
||||
COMMENT ON COLUMN agents.agentpress_tools IS 'DEPRECATED: Use config->>tools->>agentpress instead';
|
||||
COMMENT ON COLUMN agents.custom_mcps IS 'DEPRECATED: Use config->>tools->>custom_mcp instead';
|
||||
COMMENT ON COLUMN agents.avatar IS 'DEPRECATED: Use config->>metadata->>avatar instead';
|
||||
COMMENT ON COLUMN agents.avatar_color IS 'DEPRECATED: Use config->>metadata->>avatar_color instead';
|
||||
|
||||
COMMENT ON COLUMN agent_versions.system_prompt IS 'DEPRECATED: Use config->>system_prompt instead';
|
||||
COMMENT ON COLUMN agent_versions.configured_mcps IS 'DEPRECATED: Use config->>tools->>mcp instead';
|
||||
COMMENT ON COLUMN agent_versions.agentpress_tools IS 'DEPRECATED: Use config->>tools->>agentpress instead';
|
||||
COMMENT ON COLUMN agent_versions.custom_mcps IS 'DEPRECATED: Use config->>tools->>custom_mcp instead';
|
||||
|
||||
-- =====================================================
|
||||
-- 10. CREATE HELPER FUNCTIONS FOR NEW CONFIG FORMAT
|
||||
-- =====================================================
|
||||
-- Function to get agent config in a backward-compatible way
|
||||
CREATE OR REPLACE FUNCTION get_agent_config(p_agent_id UUID)
|
||||
RETURNS JSONB
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
v_agent RECORD;
|
||||
v_config JSONB;
|
||||
BEGIN
|
||||
SELECT * INTO v_agent FROM agents WHERE agent_id = p_agent_id;
|
||||
|
||||
IF NOT FOUND THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
-- If config is already populated, return it
|
||||
IF v_agent.config IS NOT NULL AND v_agent.config != '{}'::jsonb THEN
|
||||
RETURN v_agent.config;
|
||||
END IF;
|
||||
|
||||
-- Otherwise build it from legacy columns
|
||||
v_config := jsonb_build_object(
|
||||
'system_prompt', COALESCE(v_agent.system_prompt, ''),
|
||||
'tools', jsonb_build_object(
|
||||
'agentpress', (
|
||||
SELECT jsonb_object_agg(
|
||||
key,
|
||||
(value->>'enabled')::boolean
|
||||
)
|
||||
FROM jsonb_each(COALESCE(v_agent.agentpress_tools, '{}'::jsonb))
|
||||
WHERE value IS NOT NULL AND value != 'null'::jsonb
|
||||
),
|
||||
'mcp', COALESCE(v_agent.configured_mcps, '[]'::jsonb),
|
||||
'custom_mcp', COALESCE(v_agent.custom_mcps, '[]'::jsonb)
|
||||
),
|
||||
'metadata', jsonb_build_object(
|
||||
'avatar', v_agent.avatar,
|
||||
'avatar_color', v_agent.avatar_color
|
||||
)
|
||||
);
|
||||
|
||||
RETURN v_config;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- Grant permissions
|
||||
GRANT EXECUTE ON FUNCTION get_agent_config(UUID) TO authenticated, service_role;
|
||||
|
||||
-- =====================================================
|
||||
-- 11. ADD COMMENTS FOR CLARITY
|
||||
-- =====================================================
|
||||
COMMENT ON TABLE agent_workflows IS 'Agent workflows - step-by-step task execution';
|
||||
COMMENT ON TABLE workflow_steps IS 'Individual steps within an agent workflow';
|
||||
COMMENT ON TABLE workflow_executions IS 'Execution history of agent workflows';
|
||||
COMMENT ON TABLE workflow_step_executions IS 'Detailed execution logs for each workflow step';
|
||||
|
||||
COMMENT ON COLUMN agents.config IS 'Unified configuration object containing all agent settings';
|
||||
COMMENT ON COLUMN agent_versions.config IS 'Versioned configuration snapshot';
|
||||
|
||||
COMMENT ON COLUMN agents.is_default IS 'Whether this agent is the default for the account (only one allowed per account)';
|
||||
COMMENT ON COLUMN agent_triggers.execution_type IS 'Whether trigger executes an agent conversation or a workflow';
|
||||
|
||||
COMMIT;
|
|
@ -203,7 +203,8 @@ class BaseOAuthProvider(abc.ABC):
|
|||
)
|
||||
|
||||
# Store OAuth data
|
||||
await self._store_oauth_data(trigger_config.trigger_id, token_response, provider_data)
|
||||
# COMMENTED OUT: OAuth installations table deprecated
|
||||
# await self._store_oauth_data(trigger_config.trigger_id, token_response, provider_data)
|
||||
|
||||
import os
|
||||
base_url = os.getenv("WEBHOOK_BASE_URL", "http://localhost:8000")
|
||||
|
@ -246,21 +247,22 @@ class BaseOAuthProvider(abc.ABC):
|
|||
logger.error(f"Error verifying state token: {e}")
|
||||
return None
|
||||
|
||||
async def _store_oauth_data(
|
||||
self,
|
||||
trigger_id: str,
|
||||
token_response: OAuthTokenResponse,
|
||||
provider_data: Dict[str, Any]
|
||||
):
|
||||
"""Store OAuth installation data."""
|
||||
client = await self.db.client
|
||||
await client.table('oauth_installations').insert({
|
||||
'trigger_id': trigger_id,
|
||||
'provider': self.config.provider.value,
|
||||
'access_token': token_response.access_token,
|
||||
'refresh_token': token_response.refresh_token,
|
||||
'expires_in': token_response.expires_in,
|
||||
'scope': token_response.scope,
|
||||
'provider_data': provider_data,
|
||||
'installed_at': 'now()'
|
||||
}).execute()
|
||||
# COMMENTED OUT: OAuth installations functionality deprecated
|
||||
# async def _store_oauth_data(
|
||||
# self,
|
||||
# trigger_id: str,
|
||||
# token_response: OAuthTokenResponse,
|
||||
# provider_data: Dict[str, Any]
|
||||
# ):
|
||||
# """Store OAuth installation data."""
|
||||
# client = await self.db.client
|
||||
# await client.table('oauth_installations').insert({
|
||||
# 'trigger_id': trigger_id,
|
||||
# 'provider': self.config.provider.value,
|
||||
# 'access_token': token_response.access_token,
|
||||
# 'refresh_token': token_response.refresh_token,
|
||||
# 'expires_in': token_response.expires_in,
|
||||
# 'scope': token_response.scope,
|
||||
# 'provider_data': provider_data,
|
||||
# 'installed_at': 'now()'
|
||||
# }).execute()
|
|
@ -115,27 +115,31 @@ async def get_slack_status(
|
|||
|
||||
client = await db.client
|
||||
result = await client.table('agent_triggers')\
|
||||
.select('trigger_id, name, is_active')\
|
||||
.select('trigger_id, name, is_active, config')\
|
||||
.eq('agent_id', agent_id)\
|
||||
.eq('trigger_type', 'slack')\
|
||||
.execute()
|
||||
|
||||
slack_triggers = []
|
||||
for trigger in result.data:
|
||||
oauth_result = await client.table('slack_oauth_installations')\
|
||||
.select('team_name, bot_name, installed_at')\
|
||||
.eq('trigger_id', trigger['trigger_id'])\
|
||||
.execute()
|
||||
# COMMENTED OUT: OAuth installations table deprecated
|
||||
# oauth_result = await client.table('slack_oauth_installations')\
|
||||
# .select('team_name, bot_name, installed_at')\
|
||||
# .eq('trigger_id', trigger['trigger_id'])\
|
||||
# .execute()
|
||||
|
||||
oauth_data = oauth_result.data[0] if oauth_result.data else {}
|
||||
# oauth_data = oauth_result.data[0] if oauth_result.data else {}
|
||||
|
||||
# Get data from trigger config instead
|
||||
config = trigger.get('config', {})
|
||||
|
||||
slack_triggers.append({
|
||||
"trigger_id": trigger["trigger_id"],
|
||||
"name": trigger["name"],
|
||||
"is_active": trigger["is_active"],
|
||||
"workspace_name": oauth_data.get("team_name"),
|
||||
"bot_name": oauth_data.get("bot_name"),
|
||||
"installed_at": oauth_data.get("installed_at")
|
||||
"workspace_name": config.get("team_name"),
|
||||
"bot_name": config.get("bot_name"),
|
||||
"installed_at": None # No longer tracked separately
|
||||
})
|
||||
|
||||
return {
|
||||
|
@ -172,10 +176,11 @@ async def uninstall_slack_integration(
|
|||
success = await trigger_manager.delete_trigger(trigger_id)
|
||||
|
||||
if success:
|
||||
await client.table('slack_oauth_installations')\
|
||||
.delete()\
|
||||
.eq('trigger_id', trigger_id)\
|
||||
.execute()
|
||||
# COMMENTED OUT: OAuth installations table deprecated
|
||||
# await client.table('slack_oauth_installations')\
|
||||
# .delete()\
|
||||
# .eq('trigger_id', trigger_id)\
|
||||
# .execute()
|
||||
|
||||
return {"success": True, "message": "Slack integration uninstalled"}
|
||||
else:
|
||||
|
|
|
@ -169,7 +169,8 @@ class SlackOAuthManager:
|
|||
config=config
|
||||
)
|
||||
|
||||
await self._store_oauth_data(trigger_config.trigger_id, oauth_data, workspace_info, bot_info)
|
||||
# COMMENTED OUT: OAuth installations functionality deprecated
|
||||
# await self._store_oauth_data(trigger_config.trigger_id, oauth_data, workspace_info, bot_info)
|
||||
|
||||
base_url = os.getenv("WEBHOOK_BASE_URL", "http://localhost:8000")
|
||||
# Slack requires a single Event Request URL per app
|
||||
|
@ -200,25 +201,26 @@ class SlackOAuthManager:
|
|||
logger.error(f"Error verifying state token: {e}")
|
||||
return None
|
||||
|
||||
async def _store_oauth_data(
|
||||
self,
|
||||
trigger_id: str,
|
||||
oauth_data: Dict[str, Any],
|
||||
workspace_info: Dict[str, Any],
|
||||
bot_info: Dict[str, Any]
|
||||
):
|
||||
"""Store OAuth data for the trigger."""
|
||||
client = await self.db.client
|
||||
await client.table('slack_oauth_installations').insert({
|
||||
'trigger_id': trigger_id,
|
||||
'team_id': oauth_data['team_id'],
|
||||
'team_name': oauth_data['team_name'],
|
||||
'access_token': oauth_data['access_token'],
|
||||
'bot_user_id': oauth_data['bot_user_id'],
|
||||
'bot_name': bot_info.get('name'),
|
||||
'app_id': oauth_data['app_id'],
|
||||
'scope': oauth_data['scope'],
|
||||
'workspace_info': workspace_info,
|
||||
'bot_info': bot_info,
|
||||
'installed_at': 'now()'
|
||||
}).execute()
|
||||
# COMMENTED OUT: OAuth installations functionality deprecated
|
||||
# async def _store_oauth_data(
|
||||
# self,
|
||||
# trigger_id: str,
|
||||
# oauth_data: Dict[str, Any],
|
||||
# workspace_info: Dict[str, Any],
|
||||
# bot_info: Dict[str, Any]
|
||||
# ):
|
||||
# """Store OAuth data for the trigger."""
|
||||
# client = await self.db.client
|
||||
# await client.table('slack_oauth_installations').insert({
|
||||
# 'trigger_id': trigger_id,
|
||||
# 'team_id': oauth_data['team_id'],
|
||||
# 'team_name': oauth_data['team_name'],
|
||||
# 'access_token': oauth_data['access_token'],
|
||||
# 'bot_user_id': oauth_data['bot_user_id'],
|
||||
# 'bot_name': bot_info.get('name'),
|
||||
# 'app_id': oauth_data['app_id'],
|
||||
# 'scope': oauth_data['scope'],
|
||||
# 'workspace_info': workspace_info,
|
||||
# 'bot_info': bot_info,
|
||||
# 'installed_at': 'now()'
|
||||
# }).execute()
|
|
@ -152,32 +152,36 @@ async def get_integration_status(
|
|||
|
||||
client = await db.client
|
||||
result = await client.table('agent_triggers')\
|
||||
.select('trigger_id, trigger_type, name, is_active, created_at')\
|
||||
.select('trigger_id, trigger_type, name, is_active, created_at, config')\
|
||||
.eq('agent_id', agent_id)\
|
||||
.in_('trigger_type', ['slack', 'discord', 'teams'])\
|
||||
.execute()
|
||||
|
||||
integrations = []
|
||||
for trigger in result.data:
|
||||
oauth_result = await client.table('oauth_installations')\
|
||||
.select('provider, provider_data, installed_at')\
|
||||
.eq('trigger_id', trigger['trigger_id'])\
|
||||
.execute()
|
||||
# COMMENTED OUT: OAuth installations table deprecated
|
||||
# oauth_result = await client.table('oauth_installations')\
|
||||
# .select('provider, provider_data, installed_at')\
|
||||
# .eq('trigger_id', trigger['trigger_id'])\
|
||||
# .execute()
|
||||
|
||||
if oauth_result.data:
|
||||
oauth_data = oauth_result.data[0]
|
||||
provider_data = oauth_data.get('provider_data', {})
|
||||
|
||||
integrations.append({
|
||||
"trigger_id": trigger["trigger_id"],
|
||||
"provider": oauth_data["provider"],
|
||||
"name": trigger["name"],
|
||||
"is_active": trigger["is_active"],
|
||||
"workspace_name": provider_data.get("workspace_name"),
|
||||
"bot_name": provider_data.get("bot_name"),
|
||||
"installed_at": oauth_data["installed_at"],
|
||||
"created_at": trigger["created_at"]
|
||||
})
|
||||
# if oauth_result.data:
|
||||
# oauth_data = oauth_result.data[0]
|
||||
# provider_data = oauth_data.get('provider_data', {})
|
||||
|
||||
# Get data from trigger config instead
|
||||
config = trigger.get('config', {})
|
||||
|
||||
integrations.append({
|
||||
"trigger_id": trigger["trigger_id"],
|
||||
"provider": trigger["trigger_type"],
|
||||
"name": trigger["name"],
|
||||
"is_active": trigger["is_active"],
|
||||
"workspace_name": config.get("team_name") or config.get("guild_name") or config.get("organization"),
|
||||
"bot_name": config.get("bot_name"),
|
||||
"installed_at": trigger["created_at"], # Use trigger creation time
|
||||
"created_at": trigger["created_at"]
|
||||
})
|
||||
|
||||
return IntegrationStatusResponse(
|
||||
agent_id=agent_id,
|
||||
|
@ -214,10 +218,11 @@ async def uninstall_integration(
|
|||
success = await trigger_manager.delete_trigger(trigger_id)
|
||||
|
||||
if success:
|
||||
await client.table('oauth_installations')\
|
||||
.delete()\
|
||||
.eq('trigger_id', trigger_id)\
|
||||
.execute()
|
||||
# COMMENTED OUT: OAuth installations table deprecated
|
||||
# await client.table('oauth_installations')\
|
||||
# .delete()\
|
||||
# .eq('trigger_id', trigger_id)\
|
||||
# .execute()
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
|
|
Loading…
Reference in New Issue