from __future__ import annotations from typing import Any from yuxi.channels.models import ChannelIdentity, ChannelResponse, DeliveryResult from yuxi.channels.protocols.actions import ActionContext _ACTION_HANDLERS: dict[str, str] = {} def _build_response(ctx: ActionContext, adapter: Any, content_key: str = "content") -> ChannelResponse | None: content = ctx.get(content_key, ctx.get("media_url", "")) if not ctx.chat_id or not content: return None identity = ChannelIdentity( channel_id="twitch", channel_type=adapter.channel_type, channel_user_id="", channel_chat_id=ctx.chat_id, ) return ChannelResponse(identity=identity, content=content) async def handle_action(ctx: ActionContext, adapter: Any) -> DeliveryResult: if ctx.action == "send": response = _build_response(ctx, adapter, "content") if response is None: return DeliveryResult(success=False, error="missing chat_id or content") return await adapter.send(response) if ctx.action == "send_media": response = _build_response(ctx, adapter, "media_url") if response is None: return DeliveryResult(success=False, error="missing chat_id or media_url") return await adapter.send_media(ctx.chat_id, "url", response.content) unsupported_hints: dict[str, str] = { "reply": "Twitch IRC does not support message replies", "edit": "Twitch IRC does not support message editing", "unsend": "Twitch IRC does not support message deletion", "delete_message": "Twitch IRC does not support message deletion", "edit_message": "Twitch IRC does not support message editing", "reactions": "Twitch IRC does not support reactions", "send_reaction": "Twitch IRC does not support reactions", "polls": "Twitch IRC does not support polls", "native_commands": "Twitch IRC does not support native commands", "pin": "Twitch IRC does not support message pinning", "unpin": "Twitch IRC does not support message unpinning", } hint = unsupported_hints.get(ctx.action, f"unknown action: {ctx.action}") return DeliveryResult(success=False, error=hint) def supports_action(action: str) -> bool: return action in {"send", "send_media"} def describe_message_tool() -> dict[str, Any]: return { "send": { "description": "Send a text message to a Twitch channel", "parameters": { "chat_id": {"type": "string", "description": "Channel name (e.g. #channel)"}, "content": {"type": "string", "description": "Text content to send"}, }, }, "send_media": { "description": "Send a media URL to a Twitch channel (sent as text)", "parameters": { "chat_id": {"type": "string", "description": "Channel name (e.g. #channel)"}, "media_url": {"type": "string", "description": "Media URL to send"}, }, }, } def extract_target_from_args(args: dict[str, Any]) -> dict | None: chat_id = args.get("chat_id") if chat_id: return {"chat_id": chat_id} return None def resolve_execution_mode(action: str) -> str: return "send" def get_action_stats() -> dict[str, list[str]]: return { "implemented": ["send", "send_media"], "planned": [], "unsupported": [ "reply", "edit", "unsend", "reactions", "polls", "native_commands", "pin", "unpin", "send_reaction", "delete_message", "edit_message", ], }