mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-03-19 13:28:11 +08:00
fix: scheduler in feishu
This commit is contained in:
@@ -13,46 +13,70 @@ from agent.tools.ls.ls import Ls
|
|||||||
from agent.tools.memory.memory_search import MemorySearchTool
|
from agent.tools.memory.memory_search import MemorySearchTool
|
||||||
from agent.tools.memory.memory_get import MemoryGetTool
|
from agent.tools.memory.memory_get import MemoryGetTool
|
||||||
|
|
||||||
# Import env config tool
|
|
||||||
from agent.tools.env_config.env_config import EnvConfig
|
|
||||||
|
|
||||||
# Import tools with optional dependencies
|
# Import tools with optional dependencies
|
||||||
def _import_optional_tools():
|
def _import_optional_tools():
|
||||||
"""Import tools that have optional dependencies"""
|
"""Import tools that have optional dependencies"""
|
||||||
|
from common.log import logger
|
||||||
tools = {}
|
tools = {}
|
||||||
|
|
||||||
|
# EnvConfig Tool (requires python-dotenv)
|
||||||
|
try:
|
||||||
|
from agent.tools.env_config.env_config import EnvConfig
|
||||||
|
tools['EnvConfig'] = EnvConfig
|
||||||
|
except ImportError as e:
|
||||||
|
logger.error(
|
||||||
|
f"[Tools] EnvConfig tool not loaded - missing dependency: {e}\n"
|
||||||
|
f" To enable environment variable management, run:\n"
|
||||||
|
f" pip install python-dotenv>=1.0.0"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Tools] EnvConfig tool failed to load: {e}")
|
||||||
|
|
||||||
# Scheduler Tool (requires croniter)
|
# Scheduler Tool (requires croniter)
|
||||||
try:
|
try:
|
||||||
from agent.tools.scheduler.scheduler_tool import SchedulerTool
|
from agent.tools.scheduler.scheduler_tool import SchedulerTool
|
||||||
tools['SchedulerTool'] = SchedulerTool
|
tools['SchedulerTool'] = SchedulerTool
|
||||||
except ImportError:
|
except ImportError as e:
|
||||||
pass
|
logger.error(
|
||||||
|
f"[Tools] Scheduler tool not loaded - missing dependency: {e}\n"
|
||||||
|
f" To enable scheduled tasks, run:\n"
|
||||||
|
f" pip install croniter>=2.0.0"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Tools] Scheduler tool failed to load: {e}")
|
||||||
|
|
||||||
# Google Search (requires requests)
|
# Google Search (requires requests)
|
||||||
try:
|
try:
|
||||||
from agent.tools.google_search.google_search import GoogleSearch
|
from agent.tools.google_search.google_search import GoogleSearch
|
||||||
tools['GoogleSearch'] = GoogleSearch
|
tools['GoogleSearch'] = GoogleSearch
|
||||||
except ImportError:
|
except ImportError as e:
|
||||||
pass
|
logger.warning(f"[Tools] GoogleSearch tool not loaded - missing dependency: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Tools] GoogleSearch tool failed to load: {e}")
|
||||||
|
|
||||||
# File Save (may have dependencies)
|
# File Save (may have dependencies)
|
||||||
try:
|
try:
|
||||||
from agent.tools.file_save.file_save import FileSave
|
from agent.tools.file_save.file_save import FileSave
|
||||||
tools['FileSave'] = FileSave
|
tools['FileSave'] = FileSave
|
||||||
except ImportError:
|
except ImportError as e:
|
||||||
pass
|
logger.warning(f"[Tools] FileSave tool not loaded - missing dependency: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Tools] FileSave tool failed to load: {e}")
|
||||||
|
|
||||||
# Terminal (basic, should work)
|
# Terminal (basic, should work)
|
||||||
try:
|
try:
|
||||||
from agent.tools.terminal.terminal import Terminal
|
from agent.tools.terminal.terminal import Terminal
|
||||||
tools['Terminal'] = Terminal
|
tools['Terminal'] = Terminal
|
||||||
except ImportError:
|
except ImportError as e:
|
||||||
pass
|
logger.warning(f"[Tools] Terminal tool not loaded - missing dependency: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[Tools] Terminal tool failed to load: {e}")
|
||||||
|
|
||||||
return tools
|
return tools
|
||||||
|
|
||||||
# Load optional tools
|
# Load optional tools
|
||||||
_optional_tools = _import_optional_tools()
|
_optional_tools = _import_optional_tools()
|
||||||
|
EnvConfig = _optional_tools.get('EnvConfig')
|
||||||
SchedulerTool = _optional_tools.get('SchedulerTool')
|
SchedulerTool = _optional_tools.get('SchedulerTool')
|
||||||
GoogleSearch = _optional_tools.get('GoogleSearch')
|
GoogleSearch = _optional_tools.get('GoogleSearch')
|
||||||
FileSave = _optional_tools.get('FileSave')
|
FileSave = _optional_tools.get('FileSave')
|
||||||
|
|||||||
@@ -101,12 +101,21 @@ def _execute_send_message(task: dict, agent_bridge):
|
|||||||
context["isgroup"] = is_group
|
context["isgroup"] = is_group
|
||||||
context["session_id"] = receiver
|
context["session_id"] = receiver
|
||||||
|
|
||||||
# For web channel, generate a virtual request_id
|
# Channel-specific context setup
|
||||||
if channel_type == "web":
|
if channel_type == "web":
|
||||||
|
# Web channel needs request_id
|
||||||
import uuid
|
import uuid
|
||||||
request_id = f"scheduler_{task['id']}_{uuid.uuid4().hex[:8]}"
|
request_id = f"scheduler_{task['id']}_{uuid.uuid4().hex[:8]}"
|
||||||
context["request_id"] = request_id
|
context["request_id"] = request_id
|
||||||
logger.debug(f"[Scheduler] Generated request_id for web channel: {request_id}")
|
logger.debug(f"[Scheduler] Generated request_id for web channel: {request_id}")
|
||||||
|
elif channel_type == "feishu":
|
||||||
|
# Feishu channel: for scheduled tasks, send as new message (no msg_id to reply to)
|
||||||
|
# Use chat_id for groups, open_id for private chats
|
||||||
|
context["receive_id_type"] = "chat_id" if is_group else "open_id"
|
||||||
|
# Keep isgroup as is, but set msg to None (no original message to reply to)
|
||||||
|
# Feishu channel will detect this and send as new message instead of reply
|
||||||
|
context["msg"] = None
|
||||||
|
logger.debug(f"[Scheduler] Feishu: receive_id_type={context['receive_id_type']}, is_group={is_group}, receiver={receiver}")
|
||||||
|
|
||||||
# Create reply
|
# Create reply
|
||||||
reply = Reply(ReplyType.TEXT, content)
|
reply = Reply(ReplyType.TEXT, content)
|
||||||
@@ -128,9 +137,13 @@ def _execute_send_message(task: dict, agent_bridge):
|
|||||||
logger.error(f"[Scheduler] Failed to create channel: {channel_type}")
|
logger.error(f"[Scheduler] Failed to create channel: {channel_type}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[Scheduler] Failed to send message: {e}")
|
logger.error(f"[Scheduler] Failed to send message: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(f"[Scheduler] Traceback: {traceback.format_exc()}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[Scheduler] Error in _execute_send_message: {e}")
|
logger.error(f"[Scheduler] Error in _execute_send_message: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(f"[Scheduler] Traceback: {traceback.format_exc()}")
|
||||||
|
|
||||||
|
|
||||||
def _execute_tool_call(task: dict, agent_bridge):
|
def _execute_tool_call(task: dict, agent_bridge):
|
||||||
@@ -187,12 +200,18 @@ def _execute_tool_call(task: dict, agent_bridge):
|
|||||||
context["isgroup"] = is_group
|
context["isgroup"] = is_group
|
||||||
context["session_id"] = receiver
|
context["session_id"] = receiver
|
||||||
|
|
||||||
# For web channel, generate a virtual request_id
|
# Channel-specific context setup
|
||||||
if channel_type == "web":
|
if channel_type == "web":
|
||||||
|
# Web channel needs request_id
|
||||||
import uuid
|
import uuid
|
||||||
request_id = f"scheduler_{task['id']}_{uuid.uuid4().hex[:8]}"
|
request_id = f"scheduler_{task['id']}_{uuid.uuid4().hex[:8]}"
|
||||||
context["request_id"] = request_id
|
context["request_id"] = request_id
|
||||||
logger.debug(f"[Scheduler] Generated request_id for web channel: {request_id}")
|
logger.debug(f"[Scheduler] Generated request_id for web channel: {request_id}")
|
||||||
|
elif channel_type == "feishu":
|
||||||
|
# Feishu channel: for scheduled tasks, send as new message (no msg_id to reply to)
|
||||||
|
context["receive_id_type"] = "chat_id" if is_group else "open_id"
|
||||||
|
context["msg"] = None
|
||||||
|
logger.debug(f"[Scheduler] Feishu: receive_id_type={context['receive_id_type']}, is_group={is_group}, receiver={receiver}")
|
||||||
|
|
||||||
reply = Reply(ReplyType.TEXT, content)
|
reply = Reply(ReplyType.TEXT, content)
|
||||||
|
|
||||||
|
|||||||
@@ -208,8 +208,12 @@ class FeiShuChanel(ChatChannel):
|
|||||||
return
|
return
|
||||||
msg_type = "image"
|
msg_type = "image"
|
||||||
content_key = "image_key"
|
content_key = "image_key"
|
||||||
if is_group:
|
|
||||||
# 群聊中直接回复
|
# Check if we can reply to an existing message (need msg_id)
|
||||||
|
can_reply = is_group and msg and hasattr(msg, 'msg_id') and msg.msg_id
|
||||||
|
|
||||||
|
if can_reply:
|
||||||
|
# 群聊中回复已有消息
|
||||||
url = f"https://open.feishu.cn/open-apis/im/v1/messages/{msg.msg_id}/reply"
|
url = f"https://open.feishu.cn/open-apis/im/v1/messages/{msg.msg_id}/reply"
|
||||||
data = {
|
data = {
|
||||||
"msg_type": msg_type,
|
"msg_type": msg_type,
|
||||||
@@ -217,6 +221,7 @@ class FeiShuChanel(ChatChannel):
|
|||||||
}
|
}
|
||||||
res = requests.post(url=url, headers=headers, json=data, timeout=(5, 10))
|
res = requests.post(url=url, headers=headers, json=data, timeout=(5, 10))
|
||||||
else:
|
else:
|
||||||
|
# 发送新消息(私聊或群聊中无msg_id的情况,如定时任务)
|
||||||
url = "https://open.feishu.cn/open-apis/im/v1/messages"
|
url = "https://open.feishu.cn/open-apis/im/v1/messages"
|
||||||
params = {"receive_id_type": context.get("receive_id_type") or "open_id"}
|
params = {"receive_id_type": context.get("receive_id_type") or "open_id"}
|
||||||
data = {
|
data = {
|
||||||
|
|||||||
Reference in New Issue
Block a user