262 lines
12 KiB
Python
262 lines
12 KiB
Python
|
|
"""Autonomous action routes: V1, V2, per-server autonomous."""
|
||
|
|
|
||
|
|
from fastapi import APIRouter
|
||
|
|
import globals
|
||
|
|
from server_manager import server_manager
|
||
|
|
from routes.models import CustomPromptRequest
|
||
|
|
from utils.logger import get_logger
|
||
|
|
|
||
|
|
logger = get_logger('api')
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
|
||
|
|
# ========== Autonomous V1 ==========
|
||
|
|
|
||
|
|
@router.post("/autonomous/general")
|
||
|
|
async def trigger_autonomous_general(guild_id: int = None):
|
||
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
||
|
|
if guild_id is not None:
|
||
|
|
from utils.autonomous import miku_say_something_general_for_server
|
||
|
|
globals.client.loop.create_task(miku_say_something_general_for_server(guild_id))
|
||
|
|
return {"status": "ok", "message": f"Autonomous general message queued for server {guild_id}"}
|
||
|
|
else:
|
||
|
|
from utils.autonomous import miku_say_something_general
|
||
|
|
globals.client.loop.create_task(miku_say_something_general())
|
||
|
|
return {"status": "ok", "message": "Autonomous general message queued for all servers"}
|
||
|
|
else:
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/autonomous/engage")
|
||
|
|
async def trigger_autonomous_engage_user(
|
||
|
|
guild_id: int = None,
|
||
|
|
user_id: str = None,
|
||
|
|
engagement_type: str = None,
|
||
|
|
manual_trigger: str = "false"
|
||
|
|
):
|
||
|
|
manual_trigger_bool = manual_trigger.lower() in ('true', '1', 'yes')
|
||
|
|
|
||
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
||
|
|
if guild_id is not None:
|
||
|
|
from utils.autonomous import miku_engage_random_user_for_server
|
||
|
|
globals.client.loop.create_task(miku_engage_random_user_for_server(guild_id, user_id=user_id, engagement_type=engagement_type, manual_trigger=manual_trigger_bool))
|
||
|
|
|
||
|
|
msg_parts = [f"Autonomous user engagement queued for server {guild_id}"]
|
||
|
|
if user_id:
|
||
|
|
msg_parts.append(f"targeting user {user_id}")
|
||
|
|
if engagement_type:
|
||
|
|
msg_parts.append(f"with {engagement_type} engagement")
|
||
|
|
if manual_trigger_bool:
|
||
|
|
msg_parts.append("(manual trigger - bypassing cooldown)")
|
||
|
|
|
||
|
|
return {"status": "ok", "message": " ".join(msg_parts)}
|
||
|
|
else:
|
||
|
|
from utils.autonomous import miku_engage_random_user
|
||
|
|
globals.client.loop.create_task(miku_engage_random_user(user_id=user_id, engagement_type=engagement_type, manual_trigger=manual_trigger_bool))
|
||
|
|
|
||
|
|
msg_parts = ["Autonomous user engagement queued for all servers"]
|
||
|
|
if user_id:
|
||
|
|
msg_parts.append(f"targeting user {user_id}")
|
||
|
|
if engagement_type:
|
||
|
|
msg_parts.append(f"with {engagement_type} engagement")
|
||
|
|
if manual_trigger_bool:
|
||
|
|
msg_parts.append("(manual trigger - bypassing cooldown)")
|
||
|
|
|
||
|
|
return {"status": "ok", "message": " ".join(msg_parts)}
|
||
|
|
else:
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/autonomous/tweet")
|
||
|
|
async def trigger_autonomous_tweet(guild_id: int = None, tweet_url: str = None):
|
||
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
||
|
|
if guild_id is not None:
|
||
|
|
from utils.autonomous import share_miku_tweet_for_server
|
||
|
|
globals.client.loop.create_task(share_miku_tweet_for_server(guild_id, tweet_url=tweet_url))
|
||
|
|
msg = f"Autonomous tweet sharing queued for server {guild_id}"
|
||
|
|
if tweet_url:
|
||
|
|
msg += f" with URL {tweet_url}"
|
||
|
|
return {"status": "ok", "message": msg}
|
||
|
|
else:
|
||
|
|
from utils.autonomous import share_miku_tweet
|
||
|
|
globals.client.loop.create_task(share_miku_tweet(tweet_url=tweet_url))
|
||
|
|
msg = "Autonomous tweet sharing queued for all servers"
|
||
|
|
if tweet_url:
|
||
|
|
msg += f" with URL {tweet_url}"
|
||
|
|
return {"status": "ok", "message": msg}
|
||
|
|
else:
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/autonomous/custom")
|
||
|
|
async def custom_autonomous_message(req: CustomPromptRequest, guild_id: int = None):
|
||
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
||
|
|
if guild_id is not None:
|
||
|
|
from utils.autonomous import handle_custom_prompt_for_server
|
||
|
|
globals.client.loop.create_task(handle_custom_prompt_for_server(guild_id, req.prompt))
|
||
|
|
return {"status": "ok", "message": f"Custom autonomous message queued for server {guild_id}"}
|
||
|
|
else:
|
||
|
|
from utils.autonomous import handle_custom_prompt
|
||
|
|
globals.client.loop.create_task(handle_custom_prompt(req.prompt))
|
||
|
|
return {"status": "ok", "message": "Custom autonomous message queued for all servers"}
|
||
|
|
else:
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/autonomous/reaction")
|
||
|
|
async def trigger_autonomous_reaction(guild_id: int = None):
|
||
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
||
|
|
if guild_id is not None:
|
||
|
|
from utils.autonomous import miku_autonomous_reaction_for_server
|
||
|
|
globals.client.loop.create_task(miku_autonomous_reaction_for_server(guild_id, force=True))
|
||
|
|
return {"status": "ok", "message": f"Autonomous reaction queued for server {guild_id}"}
|
||
|
|
else:
|
||
|
|
from utils.autonomous import miku_autonomous_reaction
|
||
|
|
globals.client.loop.create_task(miku_autonomous_reaction(force=True))
|
||
|
|
return {"status": "ok", "message": "Autonomous reaction queued for all servers"}
|
||
|
|
else:
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/autonomous/join-conversation")
|
||
|
|
async def trigger_detect_and_join_conversation(guild_id: int = None):
|
||
|
|
logger.debug(f"Join conversation endpoint called with guild_id={guild_id}")
|
||
|
|
if globals.client and globals.client.loop and globals.client.loop.is_running():
|
||
|
|
if guild_id is not None:
|
||
|
|
logger.debug(f"Importing and calling miku_detect_and_join_conversation_for_server({guild_id}, force=True)")
|
||
|
|
from utils.autonomous import miku_detect_and_join_conversation_for_server
|
||
|
|
globals.client.loop.create_task(miku_detect_and_join_conversation_for_server(guild_id, force=True))
|
||
|
|
return {"status": "ok", "message": f"Detect and join conversation queued for server {guild_id}"}
|
||
|
|
else:
|
||
|
|
logger.debug(f"Importing and calling miku_detect_and_join_conversation() for all servers")
|
||
|
|
from utils.autonomous import miku_detect_and_join_conversation
|
||
|
|
globals.client.loop.create_task(miku_detect_and_join_conversation(force=True))
|
||
|
|
return {"status": "ok", "message": "Detect and join conversation queued for all servers"}
|
||
|
|
else:
|
||
|
|
logger.error(f"Bot not ready: client={globals.client}, loop={globals.client.loop if globals.client else None}")
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
|
||
|
|
# ========== Per-Server Autonomous ==========
|
||
|
|
|
||
|
|
@router.post("/servers/{guild_id}/autonomous/general")
|
||
|
|
async def trigger_autonomous_general_for_server(guild_id: int):
|
||
|
|
"""Trigger autonomous general message for a specific server"""
|
||
|
|
from utils.autonomous import miku_say_something_general_for_server
|
||
|
|
try:
|
||
|
|
await miku_say_something_general_for_server(guild_id)
|
||
|
|
return {"status": "ok", "message": f"Autonomous general message triggered for server {guild_id}"}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": f"Failed to trigger autonomous message: {e}"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/servers/{guild_id}/autonomous/engage")
|
||
|
|
async def trigger_autonomous_engage_for_server(
|
||
|
|
guild_id: int,
|
||
|
|
user_id: str = None,
|
||
|
|
engagement_type: str = None,
|
||
|
|
manual_trigger: str = "false"
|
||
|
|
):
|
||
|
|
"""Trigger autonomous user engagement for a specific server"""
|
||
|
|
manual_trigger_bool = manual_trigger.lower() in ('true', '1', 'yes')
|
||
|
|
|
||
|
|
from utils.autonomous import miku_engage_random_user_for_server
|
||
|
|
try:
|
||
|
|
await miku_engage_random_user_for_server(guild_id, user_id=user_id, engagement_type=engagement_type, manual_trigger=manual_trigger_bool)
|
||
|
|
|
||
|
|
msg_parts = [f"Autonomous user engagement triggered for server {guild_id}"]
|
||
|
|
if user_id:
|
||
|
|
msg_parts.append(f"targeting user {user_id}")
|
||
|
|
if engagement_type:
|
||
|
|
msg_parts.append(f"with {engagement_type} engagement")
|
||
|
|
if manual_trigger_bool:
|
||
|
|
msg_parts.append("(manual trigger - bypassing cooldown)")
|
||
|
|
|
||
|
|
return {"status": "ok", "message": " ".join(msg_parts)}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": f"Failed to trigger user engagement: {e}"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/servers/{guild_id}/autonomous/custom")
|
||
|
|
async def custom_autonomous_message_for_server(guild_id: int, req: CustomPromptRequest):
|
||
|
|
"""Send custom autonomous message to a specific server"""
|
||
|
|
from utils.autonomous import handle_custom_prompt_for_server
|
||
|
|
try:
|
||
|
|
success = await handle_custom_prompt_for_server(guild_id, req.prompt)
|
||
|
|
if success:
|
||
|
|
return {"status": "ok", "message": f"Custom autonomous message sent to server {guild_id}"}
|
||
|
|
else:
|
||
|
|
return {"status": "error", "message": f"Failed to send custom message to server {guild_id}"}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": f"Error: {e}"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/servers/{guild_id}/autonomous/tweet")
|
||
|
|
async def trigger_autonomous_tweet_for_server(guild_id: int):
|
||
|
|
"""Trigger autonomous tweet sharing for a specific server"""
|
||
|
|
from utils.autonomous import share_miku_tweet_for_server
|
||
|
|
try:
|
||
|
|
await share_miku_tweet_for_server(guild_id)
|
||
|
|
return {"status": "ok", "message": f"Autonomous tweet sharing triggered for server {guild_id}"}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": f"Failed to trigger tweet sharing: {e}"}
|
||
|
|
|
||
|
|
|
||
|
|
# ========== Autonomous V2 ==========
|
||
|
|
|
||
|
|
@router.get("/autonomous/v2/stats/{guild_id}")
|
||
|
|
async def get_v2_stats(guild_id: int):
|
||
|
|
"""Get current V2 social stats for a server"""
|
||
|
|
try:
|
||
|
|
from utils.autonomous_v2_integration import get_v2_stats_for_server
|
||
|
|
stats = get_v2_stats_for_server(guild_id)
|
||
|
|
return {"status": "ok", "guild_id": guild_id, "stats": stats}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": str(e)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/autonomous/v2/check/{guild_id}")
|
||
|
|
async def manual_v2_check(guild_id: int):
|
||
|
|
"""Manually trigger a V2 context check"""
|
||
|
|
try:
|
||
|
|
from utils.autonomous_v2_integration import manual_trigger_v2_check
|
||
|
|
|
||
|
|
if not globals.client:
|
||
|
|
return {"status": "error", "message": "Bot not ready"}
|
||
|
|
|
||
|
|
result = await manual_trigger_v2_check(guild_id, globals.client)
|
||
|
|
|
||
|
|
if isinstance(result, str):
|
||
|
|
return {"status": "error", "message": result}
|
||
|
|
|
||
|
|
return {"status": "ok", "guild_id": guild_id, "analysis": result}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": str(e)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/autonomous/v2/status")
|
||
|
|
async def get_v2_status():
|
||
|
|
"""Get V2 system status for all servers"""
|
||
|
|
try:
|
||
|
|
from utils.autonomous_v2 import autonomous_system_v2
|
||
|
|
|
||
|
|
status = {}
|
||
|
|
for guild_id in server_manager.servers:
|
||
|
|
server_config = server_manager.get_server_config(guild_id)
|
||
|
|
if server_config:
|
||
|
|
stats = autonomous_system_v2.get_stats(guild_id)
|
||
|
|
status[str(guild_id)] = {
|
||
|
|
"server_name": server_config.guild_name,
|
||
|
|
"loop_running": autonomous_system_v2.running_loops.get(guild_id, False),
|
||
|
|
"action_urgency": f"{stats.get_action_urgency():.2f}",
|
||
|
|
"loneliness": f"{stats.loneliness:.2f}",
|
||
|
|
"boredom": f"{stats.boredom:.2f}",
|
||
|
|
"excitement": f"{stats.excitement:.2f}",
|
||
|
|
"chattiness": f"{stats.chattiness:.2f}",
|
||
|
|
}
|
||
|
|
|
||
|
|
return {"status": "ok", "servers": status}
|
||
|
|
except Exception as e:
|
||
|
|
return {"status": "error", "message": str(e)}
|