Convert integrations to workflow plugins and remove old folder

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-10 16:57:22 +00:00
parent 8f52b4d550
commit ef16336084
8 changed files with 238 additions and 3 deletions

View File

@@ -1,3 +1,4 @@
"""Notification helpers for workflow plugins."""
import os
import logging
from slack_sdk import WebClient
@@ -7,7 +8,9 @@ import asyncio
logger = logging.getLogger("autometabuilder.notifications")
def send_slack_notification(message: str):
"""Send a notification to Slack."""
token = os.environ.get("SLACK_BOT_TOKEN")
channel = os.environ.get("SLACK_CHANNEL")
if not token or not channel:
@@ -21,7 +24,9 @@ def send_slack_notification(message: str):
except SlackApiError as e:
logger.error(f"Error sending Slack notification: {e}")
async def send_discord_notification_async(message: str):
"""Send Discord notification asynchronously."""
token = os.environ.get("DISCORD_BOT_TOKEN")
channel_id = os.environ.get("DISCORD_CHANNEL_ID")
if not token or not channel_id:
@@ -44,12 +49,16 @@ async def send_discord_notification_async(message: str):
except Exception as e:
logger.error(f"Error sending Discord notification: {e}")
def send_discord_notification(message: str):
"""Send a Discord notification."""
try:
asyncio.run(send_discord_notification_async(message))
except Exception as e:
logger.error(f"Error running Discord notification: {e}")
def notify_all(message: str):
"""Send notification to all configured channels."""
send_slack_notification(message)
send_discord_notification(message)

View File

@@ -8,6 +8,7 @@ Plugins are now organized into subdirectories by category:
- **backend/** - Backend infrastructure and initialization plugins (12 plugins)
- **core/** - Core workflow orchestration plugins (7 plugins)
- **tools/** - Tool execution and development plugins (7 plugins)
- **notifications/** - External notification integrations (3 plugins)
- **logic/** - Logic and comparison operations (9 plugins)
- **list/** - List/array operations (7 plugins)
- **dict/** - Dictionary/object operations (6 plugins)
@@ -18,13 +19,15 @@ Plugins are now organized into subdirectories by category:
- **var/** - Variable management (4 plugins)
- **test/** - Unit testing and assertions (5 plugins)
- **utils/** - Utility functions (7 plugins)
- **web/** - Web UI and Flask operations (26 plugins)
**Total: 90 plugins**
**Total: 93 plugins**
## Categories
- [Core Plugins](#core-plugins) - AI and context management
- [Tool Plugins](#tool-plugins) - File system and SDLC operations
- [Notification Plugins](#notification-plugins) - External notification integrations
- [Logic Plugins](#logic-plugins) - Boolean logic and comparisons
- [List Plugins](#list-plugins) - Collection operations
- [Dictionary Plugins](#dictionary-plugins) - Object/map operations
@@ -36,6 +39,7 @@ Plugins are now organized into subdirectories by category:
- [Test Plugins](#test-plugins) - Unit testing and assertions
- [Backend Plugins](#backend-plugins) - System initialization
- [Utility Plugins](#utility-plugins) - General utilities
- [Web Plugins](#web-plugins) - Web UI and Flask operations
---
@@ -172,6 +176,48 @@ Run command inside Docker container.
---
## Notification Plugins
### `notifications.slack`
Send notification to Slack.
**Inputs:**
- `message` - The message to send
- `token` - Optional Slack bot token (defaults to SLACK_BOT_TOKEN env var)
- `channel` - Optional channel (defaults to SLACK_CHANNEL env var)
**Outputs:**
- `success` - Boolean (true if sent successfully)
- `message` - Status message
- `error` - Error message (if failed)
- `skipped` - Boolean (true if skipped due to missing config)
### `notifications.discord`
Send notification to Discord.
**Inputs:**
- `message` - The message to send
- `token` - Optional Discord bot token (defaults to DISCORD_BOT_TOKEN env var)
- `channel_id` - Optional channel ID (defaults to DISCORD_CHANNEL_ID env var)
**Outputs:**
- `success` - Boolean (true if sent successfully)
- `message` - Status message
- `error` - Error message (if failed)
- `skipped` - Boolean (true if skipped due to missing config)
### `notifications.all`
Send notification to all configured channels (Slack and Discord).
**Inputs:**
- `message` - The message to send to all channels
**Outputs:**
- `success` - Boolean
- `message` - Status message
---
## Logic Plugins
### `logic.and`

View File

@@ -1,7 +1,7 @@
"""Workflow plugin: append tool results."""
import os
import re
from ....integrations.notifications import notify_all
from ...notification_helpers import notify_all
def _is_mvp_reached() -> bool:

View File

@@ -1,5 +1,5 @@
"""Workflow plugin: run tool calls."""
from ....integrations.notifications import notify_all
from ...notification_helpers import notify_all
from ..tool_calls_handler import handle_tool_calls

View File

@@ -0,0 +1,80 @@
"""Workflow plugin: send notification to all channels."""
import os
import logging
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import discord
import asyncio
logger = logging.getLogger("autometabuilder.notifications")
def _send_slack(message: str):
"""Send Slack notification."""
token = os.environ.get("SLACK_BOT_TOKEN")
channel = os.environ.get("SLACK_CHANNEL")
if not token or not channel:
logger.warning("Slack notification skipped: SLACK_BOT_TOKEN or SLACK_CHANNEL missing.")
return
client = WebClient(token=token)
try:
client.chat_postMessage(channel=channel, text=message)
logger.info("Slack notification sent successfully.")
except SlackApiError as e:
logger.error(f"Error sending Slack notification: {e}")
async def _send_discord_async(message: str):
"""Send Discord notification asynchronously."""
token = os.environ.get("DISCORD_BOT_TOKEN")
channel_id = os.environ.get("DISCORD_CHANNEL_ID")
if not token or not channel_id:
logger.warning("Discord notification skipped: DISCORD_BOT_TOKEN or DISCORD_CHANNEL_ID missing.")
return
intents = discord.Intents.default()
client = discord.Client(intents=intents)
@client.event
async def on_ready():
channel = client.get_channel(int(channel_id))
if channel:
await channel.send(message)
logger.info("Discord notification sent successfully.")
await client.close()
try:
await client.start(token)
except Exception as e:
logger.error(f"Error sending Discord notification: {e}")
def _send_discord(message: str):
"""Send Discord notification."""
try:
asyncio.run(_send_discord_async(message))
except Exception as e:
logger.error(f"Error running Discord notification: {e}")
def run(runtime, inputs):
"""
Send a notification to all configured channels (Slack and Discord).
Inputs:
message: The message to send to all channels
Returns:
dict: Contains success status for all channels
"""
message = inputs.get("message", "")
# Send to both channels
_send_slack(message)
_send_discord(message)
return {
"success": True,
"message": "Notifications sent to all channels"
}

View File

@@ -0,0 +1,59 @@
"""Workflow plugin: send Discord notification."""
import os
import logging
import discord
import asyncio
logger = logging.getLogger("autometabuilder.notifications")
async def _send_discord_notification_async(message: str, token: str, channel_id: str):
"""Send Discord notification asynchronously."""
intents = discord.Intents.default()
client = discord.Client(intents=intents)
@client.event
async def on_ready():
channel = client.get_channel(int(channel_id))
if channel:
await channel.send(message)
logger.info("Discord notification sent successfully.")
await client.close()
try:
await client.start(token)
except Exception as e:
logger.error(f"Error sending Discord notification: {e}")
raise
def run(runtime, inputs):
"""
Send a notification to Discord.
Inputs:
message: The message to send
token: Optional Discord bot token (defaults to DISCORD_BOT_TOKEN env var)
channel_id: Optional channel ID (defaults to DISCORD_CHANNEL_ID env var)
Returns:
dict: Contains success status and any error message
"""
message = inputs.get("message", "")
token = inputs.get("token") or os.environ.get("DISCORD_BOT_TOKEN")
channel_id = inputs.get("channel_id") or os.environ.get("DISCORD_CHANNEL_ID")
if not token or not channel_id:
logger.warning("Discord notification skipped: DISCORD_BOT_TOKEN or DISCORD_CHANNEL_ID missing.")
return {
"success": False,
"skipped": True,
"error": "DISCORD_BOT_TOKEN or DISCORD_CHANNEL_ID missing"
}
try:
asyncio.run(_send_discord_notification_async(message, token, channel_id))
return {"success": True, "message": "Discord notification sent"}
except Exception as e:
logger.error(f"Error running Discord notification: {e}")
return {"success": False, "error": str(e)}

View File

@@ -0,0 +1,41 @@
"""Workflow plugin: send Slack notification."""
import os
import logging
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
logger = logging.getLogger("autometabuilder.notifications")
def run(runtime, inputs):
"""
Send a notification to Slack.
Inputs:
message: The message to send
token: Optional Slack bot token (defaults to SLACK_BOT_TOKEN env var)
channel: Optional channel (defaults to SLACK_CHANNEL env var)
Returns:
dict: Contains success status and any error message
"""
message = inputs.get("message", "")
token = inputs.get("token") or os.environ.get("SLACK_BOT_TOKEN")
channel = inputs.get("channel") or os.environ.get("SLACK_CHANNEL")
if not token or not channel:
logger.warning("Slack notification skipped: SLACK_BOT_TOKEN or SLACK_CHANNEL missing.")
return {
"success": False,
"skipped": True,
"error": "SLACK_BOT_TOKEN or SLACK_CHANNEL missing"
}
client = WebClient(token=token)
try:
client.chat_postMessage(channel=channel, text=message)
logger.info("Slack notification sent successfully.")
return {"success": True, "message": "Slack notification sent"}
except SlackApiError as e:
logger.error(f"Error sending Slack notification: {e}")
return {"success": False, "error": str(e)}