diff --git a/docs/cron.md b/docs/cron.md index 6483fa137..b570d5df3 100644 --- a/docs/cron.md +++ b/docs/cron.md @@ -36,6 +36,8 @@ This is the default for the cron tool. When the job fires, PicoClaw sends the saved message back through the agent loop as a new agent turn. Use this for scheduled work that may need reasoning, tools, or a generated reply. +Because the saved `message` is replayed as a new user-style input, write it from the user's perspective or as direct instructions to the agent. Prefer wording such as `check the repo every hour and tell me if there is a new release` over third-person wording such as `check the repo and notify the user`. + ### `deliver: true` When the job fires, PicoClaw publishes the saved message directly to the target channel and recipient without agent processing. @@ -50,6 +52,23 @@ For command jobs, `deliver` is forced to `false` when the job is created. The sa The current CLI `picoclaw cron add` command does not expose a `command` flag. +## Writing Job Messages + +For normal cron jobs without `command`, the saved `payload.message` becomes the next input sent to the agent when the job fires. In practice, that means the job message should read like something the user would say to the agent. + +Recommended style: + +- Use first-person or direct-address wording such as `tell me`, `remind me`, `reply in Chinese`, `do not reply if nothing changed` +- Be explicit about the quiet case if needed, for example `If there is no update, do not reply` +- Avoid third-person wording such as `notify the user`, because the model may continue replying in third person + +Examples: + +```text +Good: Check gdsfactory/gdsfactory every hour. If there is a new release, tell me in Chinese and summarize the changes. If nothing changed, do not reply. +Bad: Check gdsfactory/gdsfactory every hour. If there is a new release, notify the user and summarize the changes. +``` + ## Config and Security Gates ### `tools.cron` diff --git a/docs/tools_configuration.md b/docs/tools_configuration.md index adee9244a..69380b23a 100644 --- a/docs/tools_configuration.md +++ b/docs/tools_configuration.md @@ -252,6 +252,8 @@ The cron tool is used for scheduling periodic tasks. | `allow_command` | bool | true | Allow command jobs without extra confirmation | | `exec_timeout_minutes` | int | 5 | Execution timeout in minutes, 0 means no limit | +For normal cron jobs without `command`, the saved `message` is later replayed into the agent loop as a new user-style message. Write it from the user's perspective, for example `check the repo every hour and tell me if there is a new release`, not `notify the user`. + For schedule types, execution modes (`deliver`, agent turn, and command jobs), persistence, and the current command-security gates, see [Scheduled Tasks and Cron Jobs](cron.md). ## MCP Tool diff --git a/docs/zh/tools_configuration.md b/docs/zh/tools_configuration.md index 63ac5000b..f6ccd5605 100644 --- a/docs/zh/tools_configuration.md +++ b/docs/zh/tools_configuration.md @@ -234,6 +234,8 @@ Cron 工具用于调度周期性任务。 | `exec_timeout_minutes` | int | 5 | 执行超时时间(分钟),0 表示无限制 | | `allow_command` | bool | false | 允许 cron 任务执行 shell 命令 | +对于不带 `command` 的普通 cron 任务,保存下来的 `message` 会在任务触发时重新作为一条新的“用户消息”送回 agent。编写时应使用用户视角/直接对 agent 说话的口吻,例如 `每小时检查仓库更新,如果有新版本告诉我`,而不是 `如果有更新就通知用户`。 + ## MCP 工具 MCP 工具支持与外部 Model Context Protocol 服务器集成。 diff --git a/pkg/tools/cron.go b/pkg/tools/cron.go index c6ac3a129..60d701ae1 100644 --- a/pkg/tools/cron.go +++ b/pkg/tools/cron.go @@ -73,7 +73,7 @@ func (t *CronTool) Name() string { // Description returns the tool description func (t *CronTool) Description() string { - return "Schedule reminders, tasks, or system commands. IMPORTANT: When user asks to be reminded or scheduled, you MUST call this tool. Use 'at_seconds' for one-time reminders (e.g., 'remind me in 10 minutes' → at_seconds=600). Use 'every_seconds' ONLY for recurring tasks (e.g., 'every 2 hours' → every_seconds=7200). Use 'cron_expr' for complex recurring schedules. Use 'command' to execute shell commands directly." + return "Schedule reminders, tasks, or system commands. IMPORTANT: When user asks to be reminded or scheduled, you MUST call this tool. For normal reminder/task jobs, write 'message' as the user's request to the agent in first-person/direct-address style (for example, 'check the repo every hour and tell me if there is a new release'), not third-person text like 'notify the user'. Use 'at_seconds' for one-time reminders (e.g., 'remind me in 10 minutes' → at_seconds=600). Use 'every_seconds' ONLY for recurring tasks (e.g., 'every 2 hours' → every_seconds=7200). Use 'cron_expr' for complex recurring schedules. Use 'command' to execute shell commands directly." } // Parameters returns the tool parameters schema @@ -88,7 +88,7 @@ func (t *CronTool) Parameters() map[string]any { }, "message": map[string]any{ "type": "string", - "description": "The reminder/task message to display when triggered. If 'command' is used, this describes what the command does.", + "description": "The reminder/task message saved with the job. For normal cron jobs, this will be sent back into the agent loop as a new user-style message, so phrase it from the user's perspective (e.g. 'check the repo and tell me if there is an update', not 'notify the user'). If 'command' is used, this describes what the command does.", }, "command": map[string]any{ "type": "string",