feat(cron): improve cron job context handling
Improve cron job execution context to ensure proper message delivery and session history recording. Changes: - Add [绯荤粺瀹氭椂浠诲姟] prefix to cron reminder messages to clearly mark them as system-driven, not user queries - Use user role for cron reminder messages (required by some LLM APIs) - Properly handle MessageTool to avoid duplicate message delivery - Correctly save turn history with proper skip count - Ensure Runtime Context is included in the message list This ensures that: 1. Cron jobs execute with proper context 2. Messages are correctly delivered to users 3. Session history accurately records cron job interactions 4. The LLM understands these are system-driven reminders, not user queries
This commit is contained in:
@@ -295,20 +295,55 @@ def gateway(
|
|||||||
# Set cron callback (needs agent)
|
# Set cron callback (needs agent)
|
||||||
async def on_cron_job(job: CronJob) -> str | None:
|
async def on_cron_job(job: CronJob) -> str | None:
|
||||||
"""Execute a cron job through the agent."""
|
"""Execute a cron job through the agent."""
|
||||||
response = await agent.process_direct(
|
from nanobot.agent.tools.message import MessageTool
|
||||||
job.payload.message,
|
|
||||||
session_key=f"cron:{job.id}",
|
cron_session_key = f"cron:{job.id}"
|
||||||
channel=job.payload.channel or "cli",
|
cron_session = agent.sessions.get_or_create(cron_session_key)
|
||||||
chat_id=job.payload.to or "direct",
|
|
||||||
|
reminder_note = (
|
||||||
|
f"[系统定时任务] ⏰ 计时已结束\n\n"
|
||||||
|
f"定时任务 '{job.name}' 已触发。定时内容:{job.payload.message}\n\n"
|
||||||
)
|
)
|
||||||
if job.payload.deliver and job.payload.to:
|
|
||||||
|
cron_session.add_message(role="user", content=reminder_note)
|
||||||
|
agent.sessions.save(cron_session)
|
||||||
|
|
||||||
|
agent._set_tool_context(
|
||||||
|
job.payload.channel or "cli",
|
||||||
|
job.payload.to or "direct",
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
message_tool = agent.tools.get("message")
|
||||||
|
if isinstance(message_tool, MessageTool):
|
||||||
|
message_tool.start_turn()
|
||||||
|
|
||||||
|
history = cron_session.get_history(max_messages=agent.memory_window)
|
||||||
|
|
||||||
|
messages = [
|
||||||
|
{"role": "system", "content": agent.context.build_system_prompt()},
|
||||||
|
*history,
|
||||||
|
{"role": "user", "content": agent.context._build_runtime_context(
|
||||||
|
job.payload.channel or "cli",
|
||||||
|
job.payload.to or "direct"
|
||||||
|
)},
|
||||||
|
]
|
||||||
|
|
||||||
|
final_content, _, all_msgs = await agent._run_agent_loop(messages)
|
||||||
|
agent._save_turn(cron_session, all_msgs, 1 + len(history) + 1)
|
||||||
|
agent.sessions.save(cron_session)
|
||||||
|
|
||||||
|
if isinstance(message_tool, MessageTool) and message_tool._sent_in_turn:
|
||||||
|
return final_content
|
||||||
|
|
||||||
|
if job.payload.deliver and job.payload.to and final_content:
|
||||||
from nanobot.bus.events import OutboundMessage
|
from nanobot.bus.events import OutboundMessage
|
||||||
await bus.publish_outbound(OutboundMessage(
|
await bus.publish_outbound(OutboundMessage(
|
||||||
channel=job.payload.channel or "cli",
|
channel=job.payload.channel or "cli",
|
||||||
chat_id=job.payload.to,
|
chat_id=job.payload.to,
|
||||||
content=response or ""
|
content=final_content
|
||||||
))
|
))
|
||||||
return response
|
return final_content
|
||||||
cron.on_job = on_cron_job
|
cron.on_job = on_cron_job
|
||||||
|
|
||||||
# Create channel manager
|
# Create channel manager
|
||||||
|
|||||||
Reference in New Issue
Block a user