fix: inject agent_id into system prompt for all WS handlers + enhance schedule_delete

- All 5 WS handlers (lingxi/feishu/orange/suyao/tiantian) now inject agent_id
  into LLM system prompt so agents know their own ID for schedule_list calls
- schedule_delete_tool now supports agent_id parameter for ownership checks
  and bulk delete by agent_id
- SCHEDULE_DELETE_SCHEMA updated: required fields now empty, supports
  both schedule_id and agent_id params

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
renjianbo
2026-05-04 22:31:11 +08:00
parent b8b01254ca
commit d895922438
6 changed files with 101 additions and 21 deletions

View File

@@ -1848,12 +1848,20 @@ async def schedule_list_tool(agent_id: str) -> str:
return json.dumps({"error": f"查询定时任务失败: {e}"}, ensure_ascii=False)
async def schedule_delete_tool(schedule_id: str) -> str:
async def schedule_delete_tool(
schedule_id: str = "",
agent_id: str = "",
) -> str:
"""
删除指定的定时任务。
支持三种删除方式:
1. 按 schedule_id 精确删除
2. 按 agent_id 删除该 Agent 下所有定时任务(批量清理)
Args:
schedule_id: 定时任务 ID
schedule_id: 定时任务 ID(精确删除时使用)
agent_id: Agent ID批量删除该 Agent 的所有任务时使用,或用于校验 schedule_id 所属权)
Returns:
删除结果
@@ -1862,22 +1870,65 @@ async def schedule_delete_tool(schedule_id: str) -> str:
from app.core.database import SessionLocal
from app.models.agent_schedule import AgentSchedule
if not schedule_id and not agent_id:
return json.dumps({
"error": "missing_params",
"message": "请提供 schedule_id删除单个或 agent_id批量删除该 Agent 的所有定时任务)",
}, ensure_ascii=False)
db = SessionLocal()
try:
schedule = db.query(AgentSchedule).filter(AgentSchedule.id == schedule_id).first()
if not schedule:
return json.dumps({"error": f"定时任务不存在: {schedule_id}"}, ensure_ascii=False)
if schedule_id:
# 按 ID 精确删除
schedule = db.query(AgentSchedule).filter(AgentSchedule.id == schedule_id).first()
if not schedule:
db.close()
return json.dumps({"error": f"定时任务不存在: {schedule_id}"}, ensure_ascii=False)
name = schedule.name
db.delete(schedule)
db.commit()
# 所有权校验:如果提供了 agent_id确保该 schedule 属于此 Agent
if agent_id and schedule.agent_id != agent_id:
db.close()
return json.dumps({
"error": "permission_denied",
"message": f"定时任务「{schedule.name}」不属于 Agent {agent_id}",
}, ensure_ascii=False)
return json.dumps({
"success": True,
"message": f"定时任务「{name}」已删除",
}, ensure_ascii=False)
name = schedule.name
db.delete(schedule)
db.commit()
db.close()
return json.dumps({
"success": True,
"message": f"定时任务「{name}」已删除",
}, ensure_ascii=False)
elif agent_id:
# 批量删除该 Agent 的所有定时任务
schedules = db.query(AgentSchedule).filter(AgentSchedule.agent_id == agent_id).all()
if not schedules:
db.close()
return json.dumps({
"success": True,
"message": f"Agent {agent_id} 没有定时任务需要删除",
"deleted_count": 0,
}, ensure_ascii=False)
names = [s.name for s in schedules]
count = len(schedules)
for s in schedules:
db.delete(s)
db.commit()
db.close()
return json.dumps({
"success": True,
"message": f"已删除 {count} 个定时任务:{', '.join(names)}",
"deleted_count": count,
}, ensure_ascii=False)
finally:
db.close()
try:
db.close()
except Exception:
pass
except Exception as e:
logger.error(f"schedule_delete 工具执行失败: {e}", exc_info=True)
return json.dumps({"error": f"删除定时任务失败: {e}"}, ensure_ascii=False)
@@ -2131,16 +2182,25 @@ SCHEDULE_DELETE_SCHEMA = {
"type": "function",
"function": {
"name": "schedule_delete",
"description": "删除指定的定时任务。",
"description": (
"删除定时任务。支持两种方式:"
"1) 提供 schedule_id 精确删除单个任务;"
"2) 提供 agent_id 批量删除该 Agent 的所有任务。"
"建议同时提供 agent_id 以校验所有权。"
),
"parameters": {
"type": "object",
"properties": {
"schedule_id": {
"type": "string",
"description": "定时任务 ID可从 schedule_list 查询获得)",
"description": "定时任务 ID精确删除单个任务时使用,可从 schedule_list 查询获得)",
},
"agent_id": {
"type": "string",
"description": "Agent ID用于校验 schedule_id 的所属权,或批量删除该 Agent 的所有任务)",
},
},
"required": ["schedule_id"],
"required": [],
},
},
}

View File

@@ -176,7 +176,11 @@ async def _handle_message_async(data):
config = AgentConfig(
name=agent.name or "agent",
system_prompt=system_prompt,
system_prompt=system_prompt + (
f"\n\n## 系统信息\n"
f"你的 Agent ID 是: {agent.id}\n"
f"在调用 schedule_list、schedule_delete 等工具时,使用此 ID 作为 agent_id 参数。"
),
llm=AgentLLMConfig(
model=model,
provider=provider,

View File

@@ -166,7 +166,11 @@ async def _handle_message_async(data):
config = AgentConfig(
name=agent.name or "灵犀",
system_prompt=system_prompt,
system_prompt=system_prompt + (
f"\n\n## 系统信息\n"
f"你的 Agent ID 是: {agent.id}\n"
f"在调用 schedule_list、schedule_delete 等工具时,使用此 ID 作为 agent_id 参数。"
),
llm=AgentLLMConfig(
model=model, provider=provider,
temperature=temperature, max_iterations=max_iterations,

View File

@@ -180,7 +180,11 @@ async def _handle_message_async(data):
config = AgentConfig(
name=agent.name or "橙子助手",
system_prompt=system_prompt,
system_prompt=system_prompt + (
f"\n\n## 系统信息\n"
f"你的 Agent ID 是: {agent.id}\n"
f"在调用 schedule_list、schedule_delete 等工具时,使用此 ID 作为 agent_id 参数。"
),
llm=AgentLLMConfig(
model=model,
provider=provider,

View File

@@ -180,7 +180,11 @@ async def _handle_message_async(data):
config = AgentConfig(
name=agent.name or "苏瑶",
system_prompt=system_prompt,
system_prompt=system_prompt + (
f"\n\n## 系统信息\n"
f"你的 Agent ID 是: {agent.id}\n"
f"在调用 schedule_list、schedule_delete 等工具时,使用此 ID 作为 agent_id 参数。"
),
llm=AgentLLMConfig(
model=model,
provider=provider,

View File

@@ -164,7 +164,11 @@ async def _handle_message_async(data):
config = AgentConfig(
name=agent.name or "甜甜",
system_prompt=system_prompt,
system_prompt=system_prompt + (
f"\n\n## 系统信息\n"
f"你的 Agent ID 是: {agent.id}\n"
f"在调用 schedule_list、schedule_delete 等工具时,使用此 ID 作为 agent_id 参数。"
),
llm=AgentLLMConfig(
model=model, provider=provider,
temperature=temperature, max_iterations=max_iterations,