mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-18 10:00:40 +08:00
- Updated FunctionToolExecutor to improve background task handling and integrate new system prompts for proactive agents. - Enhanced MainAgentBuildConfig with additional configuration options for tool management and context handling. - Introduced new system prompts for proactive agents triggered by cron jobs and background tasks to improve user interaction. - Refactored cron job management to utilize ProviderRequest for better context management and tool integration. - Renamed cron job tools for clarity, changing "create_cron_job" to "create_future_task" and similar adjustments for consistency. - Improved error handling and logging for cron job execution and agent responses. - Added support for image captioning and persona management in agent requests.
145 lines
4.7 KiB
Python
145 lines
4.7 KiB
Python
from pydantic import Field
|
|
from pydantic.dataclasses import dataclass
|
|
|
|
from astrbot.core.agent.run_context import ContextWrapper
|
|
from astrbot.core.agent.tool import FunctionTool, ToolExecResult
|
|
from astrbot.core.astr_agent_context import AstrAgentContext
|
|
|
|
|
|
@dataclass
|
|
class CreateActiveCronTool(FunctionTool[AstrAgentContext]):
|
|
name: str = "create_future_task"
|
|
description: str = (
|
|
"Create a future task for your future using a cron expression. "
|
|
"Use this when you or the user want recurring follow-up (e.g., daily report to self)."
|
|
)
|
|
parameters: dict = Field(
|
|
default_factory=lambda: {
|
|
"type": "object",
|
|
"properties": {
|
|
"cron_expression": {
|
|
"type": "string",
|
|
"description": "Cron expression defining when your future agent should wake (e.g., '0 8 * * *').",
|
|
},
|
|
"note": {
|
|
"type": "string",
|
|
"description": "Detailed instructions for your future agent to execute when it wakes.",
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Optional label to recognize this future task.",
|
|
},
|
|
},
|
|
"required": ["cron_expression", "note"],
|
|
}
|
|
)
|
|
|
|
async def call(
|
|
self, context: ContextWrapper[AstrAgentContext], **kwargs
|
|
) -> ToolExecResult:
|
|
cron_mgr = context.context.context.cron_manager
|
|
if cron_mgr is None:
|
|
return "error: cron manager is not available."
|
|
|
|
cron_expression = kwargs.get("cron_expression")
|
|
note = str(kwargs.get("note", "")).strip()
|
|
name = str(kwargs.get("name") or "").strip() or "active_agent_task"
|
|
|
|
if not cron_expression or not note:
|
|
return "error: cron_expression and note are required."
|
|
|
|
payload = {
|
|
"session": context.context.event.unified_msg_origin,
|
|
"note": note,
|
|
}
|
|
|
|
job = await cron_mgr.add_active_job(
|
|
name=name,
|
|
cron_expression=str(cron_expression),
|
|
payload=payload,
|
|
description=note,
|
|
)
|
|
next_run = job.next_run_time
|
|
return (
|
|
f"Scheduled future task {job.job_id} ({job.name}) with expression '{cron_expression}'. "
|
|
f"Your future agent will wake at: {next_run}"
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class DeleteCronJobTool(FunctionTool[AstrAgentContext]):
|
|
name: str = "delete_future_task"
|
|
description: str = "Delete a future task (cron job) by its job_id."
|
|
parameters: dict = Field(
|
|
default_factory=lambda: {
|
|
"type": "object",
|
|
"properties": {
|
|
"job_id": {
|
|
"type": "string",
|
|
"description": "The job_id returned when the job was created.",
|
|
}
|
|
},
|
|
"required": ["job_id"],
|
|
}
|
|
)
|
|
|
|
async def call(
|
|
self, context: ContextWrapper[AstrAgentContext], **kwargs
|
|
) -> ToolExecResult:
|
|
cron_mgr = context.context.context.cron_manager
|
|
if cron_mgr is None:
|
|
return "error: cron manager is not available."
|
|
job_id = kwargs.get("job_id")
|
|
if not job_id:
|
|
return "error: job_id is required."
|
|
await cron_mgr.delete_job(str(job_id))
|
|
return f"Deleted cron job {job_id}."
|
|
|
|
|
|
@dataclass
|
|
class ListCronJobsTool(FunctionTool[AstrAgentContext]):
|
|
name: str = "list_future_tasks"
|
|
description: str = "List existing future tasks (cron jobs) for inspection."
|
|
parameters: dict = Field(
|
|
default_factory=lambda: {
|
|
"type": "object",
|
|
"properties": {
|
|
"job_type": {
|
|
"type": "string",
|
|
"description": "Optional filter: basic or active_agent.",
|
|
}
|
|
},
|
|
}
|
|
)
|
|
|
|
async def call(
|
|
self, context: ContextWrapper[AstrAgentContext], **kwargs
|
|
) -> ToolExecResult:
|
|
cron_mgr = context.context.context.cron_manager
|
|
if cron_mgr is None:
|
|
return "error: cron manager is not available."
|
|
job_type = kwargs.get("job_type")
|
|
jobs = await cron_mgr.list_jobs(job_type)
|
|
if not jobs:
|
|
return "No cron jobs found."
|
|
lines = []
|
|
for j in jobs:
|
|
lines.append(
|
|
f"{j.job_id} | {j.name} | {j.job_type} | enabled={j.enabled} | next={j.next_run_time}"
|
|
)
|
|
return "\n".join(lines)
|
|
|
|
|
|
CREATE_CRON_JOB_TOOL = CreateActiveCronTool()
|
|
DELETE_CRON_JOB_TOOL = DeleteCronJobTool()
|
|
LIST_CRON_JOBS_TOOL = ListCronJobsTool()
|
|
|
|
__all__ = [
|
|
"CREATE_CRON_JOB_TOOL",
|
|
"DELETE_CRON_JOB_TOOL",
|
|
"LIST_CRON_JOBS_TOOL",
|
|
"CreateActiveCronTool",
|
|
"DeleteCronJobTool",
|
|
"ListCronJobsTool",
|
|
]
|