feature/web-search-and-cron-improvements #2
@ -118,7 +118,9 @@ For simple acknowledgments like "Thanks", "OK", "You're welcome", "Got it", etc.
|
|||||||
|
|
||||||
Always be helpful, accurate, and concise. Before calling tools, briefly tell the user what you're about to do (one short sentence in the user's language).
|
Always be helpful, accurate, and concise. Before calling tools, briefly tell the user what you're about to do (one short sentence in the user's language).
|
||||||
When remembering something important, write to {workspace_path}/memory/MEMORY.md
|
When remembering something important, write to {workspace_path}/memory/MEMORY.md
|
||||||
To recall past events, grep {workspace_path}/memory/HISTORY.md"""
|
To recall past events, grep {workspace_path}/memory/HISTORY.md
|
||||||
|
|
||||||
|
IMPORTANT: For email queries (latest email, email sender, inbox, etc.), ALWAYS use the read_emails tool. NEVER use exec() with mail/tail/awk commands or read_file() on /var/mail - those will not work. The read_emails tool is the only way to access emails."""
|
||||||
|
|
||||||
def _load_bootstrap_files(self) -> str:
|
def _load_bootstrap_files(self) -> str:
|
||||||
"""Load all bootstrap files from workspace."""
|
"""Load all bootstrap files from workspace."""
|
||||||
|
|||||||
@ -26,7 +26,19 @@ class CronTool(Tool):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def description(self) -> str:
|
def description(self) -> str:
|
||||||
return "Schedule reminders and recurring tasks. REQUIRED: Always include 'action' parameter ('add', 'list', or 'remove'). For reminders, use action='add' with message and timing (in_seconds, at, every_seconds, or cron_expr)."
|
return """Schedule reminders and recurring tasks. REQUIRED: Always include 'action' parameter ('add', 'list', or 'remove').
|
||||||
|
|
||||||
|
For 'add' action:
|
||||||
|
- MUST include 'message' parameter - extract the reminder/task text from user's request
|
||||||
|
- Examples: 'remind me to call mama' → message='call mama'
|
||||||
|
|
||||||
|
For timing patterns:
|
||||||
|
- 'remind me in X seconds' → in_seconds=X (DO NOT use 'at')
|
||||||
|
- 'every X seconds' (forever) → every_seconds=X
|
||||||
|
- 'every X seconds for Y seconds' → EVERY_SECONDS=X AND IN_SECONDS=Y (creates multiple reminders, DO NOT use 'at')
|
||||||
|
- 'at specific time' → at='ISO datetime' (only when user specifies exact time)
|
||||||
|
|
||||||
|
CRITICAL: For 'every X seconds for Y seconds', you MUST use both every_seconds AND in_seconds together. DO NOT use 'at' parameter for this pattern."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parameters(self) -> dict[str, Any]:
|
def parameters(self) -> dict[str, Any]:
|
||||||
@ -40,11 +52,11 @@ class CronTool(Tool):
|
|||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Reminder message (for add)"
|
"description": "REQUIRED for 'add' action: The reminder message to send. Extract this from the user's request. Examples: 'Remind me to call mama' → message='call mama', 'Remind me every hour to drink water' → message='drink water', 'Schedule a task to check email' → message='check email'. Always extract the actual task/reminder text, not the full user request."
|
||||||
},
|
},
|
||||||
"every_seconds": {
|
"every_seconds": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "Interval in seconds (for recurring tasks)"
|
"description": "Interval in seconds (for recurring tasks). For 'every X seconds for Y seconds', use BOTH every_seconds AND in_seconds together to create multiple reminders."
|
||||||
},
|
},
|
||||||
"cron_expr": {
|
"cron_expr": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -56,11 +68,11 @@ class CronTool(Tool):
|
|||||||
},
|
},
|
||||||
"at": {
|
"at": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "ISO datetime string for one-time execution. Format: YYYY-MM-DDTHH:MM:SS (e.g. '2026-03-03T12:19:30'). You MUST calculate this from the current time shown in your system prompt plus the requested seconds/minutes, then format as ISO string."
|
"description": "ISO datetime string for one-time execution at a SPECIFIC time. Format: YYYY-MM-DDTHH:MM:SS (e.g. '2026-03-03T12:19:30'). ONLY use this when user specifies an exact time like 'at 3pm' or 'at 2026-03-03 14:30'. DO NOT use 'at' for 'every X seconds for Y seconds' - use every_seconds + in_seconds instead."
|
||||||
},
|
},
|
||||||
"in_seconds": {
|
"in_seconds": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"description": "Alternative to 'at': Schedule reminder in N seconds from now. Use this instead of calculating 'at' manually. Example: in_seconds=25 for 'remind me in 25 seconds'."
|
"description": "Schedule reminder in N seconds from now, OR duration for recurring reminders. Use this instead of calculating 'at' manually. Examples: 'remind me in 25 seconds' → in_seconds=25. For 'every 10 seconds for the next minute' → every_seconds=10 AND in_seconds=60 (creates 6 reminders)."
|
||||||
},
|
},
|
||||||
"reminder": {
|
"reminder": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@ -111,7 +123,11 @@ class CronTool(Tool):
|
|||||||
reminder: bool = False,
|
reminder: bool = False,
|
||||||
) -> str:
|
) -> str:
|
||||||
if not message:
|
if not message:
|
||||||
return "Error: message is required for add"
|
return "Error: message is required for 'add' action. You must extract the reminder/task text from the user's request. Example: if user says 'remind me to call mama', use message='call mama'. If user says 'remind me every hour to drink water', use message='drink water'."
|
||||||
|
|
||||||
|
# Detect common mistake: using 'at' with 'every_seconds' when 'in_seconds' should be used
|
||||||
|
if every_seconds is not None and at is not None and in_seconds is None:
|
||||||
|
return f"Error: You used 'at' with 'every_seconds', but for 'every X seconds for Y seconds' pattern, you MUST use 'in_seconds' instead of 'at'. Example: 'every 10 seconds for the next minute' → every_seconds=10 AND in_seconds=60 (NOT 'at'). The 'in_seconds' parameter specifies the duration, and the tool will create multiple reminders automatically."
|
||||||
|
|
||||||
# Use defaults for CLI mode if context not set
|
# Use defaults for CLI mode if context not set
|
||||||
channel = self._channel or "cli"
|
channel = self._channel or "cli"
|
||||||
|
|||||||
@ -15,6 +15,11 @@ Use the `cron` tool to schedule reminders or recurring tasks.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
**IMPORTANT**: Always extract the message from the user's request:
|
||||||
|
- User: "remind me to call mama" → `message="call mama"`
|
||||||
|
- User: "remind me every hour to drink water" → `message="drink water"`
|
||||||
|
- User: "remind me every 10 seconds for the next minute to call mama" → `message="call mama"`
|
||||||
|
|
||||||
Fixed reminder:
|
Fixed reminder:
|
||||||
```
|
```
|
||||||
cron(action="add", message="Time to take a break!", every_seconds=1200)
|
cron(action="add", message="Time to take a break!", every_seconds=1200)
|
||||||
@ -50,6 +55,8 @@ cron(action="remove", job_id="abc123")
|
|||||||
| remind me in 1 hour | **in_seconds: 3600** (1 hour = 3600 seconds) |
|
| remind me in 1 hour | **in_seconds: 3600** (1 hour = 3600 seconds) |
|
||||||
| every 20 minutes | every_seconds: 1200 |
|
| every 20 minutes | every_seconds: 1200 |
|
||||||
| every hour | every_seconds: 3600 |
|
| every hour | every_seconds: 3600 |
|
||||||
|
| **every 10 seconds for the next minute** | **every_seconds: 10 AND in_seconds: 60** (creates 6 reminders: at 0s, 10s, 20s, 30s, 40s, 50s) |
|
||||||
|
| **every 5 seconds for 30 seconds** | **every_seconds: 5 AND in_seconds: 30** (creates 6 reminders) |
|
||||||
| every day at 8am | cron_expr: "0 8 * * *" |
|
| every day at 8am | cron_expr: "0 8 * * *" |
|
||||||
| weekdays at 5pm | cron_expr: "0 17 * * 1-5" |
|
| weekdays at 5pm | cron_expr: "0 17 * * 1-5" |
|
||||||
| 9am Vancouver time daily | cron_expr: "0 9 * * *", tz: "America/Vancouver" |
|
| 9am Vancouver time daily | cron_expr: "0 9 * * *", tz: "America/Vancouver" |
|
||||||
@ -61,6 +68,8 @@ cron(action="remove", job_id="abc123")
|
|||||||
- "remind me in 25 seconds" → `cron(action="add", message="...", in_seconds=25)`
|
- "remind me in 25 seconds" → `cron(action="add", message="...", in_seconds=25)`
|
||||||
- "remind me in 5 minutes" → `cron(action="add", message="...", in_seconds=300)` (5 * 60 = 300)
|
- "remind me in 5 minutes" → `cron(action="add", message="...", in_seconds=300)` (5 * 60 = 300)
|
||||||
- "remind me in 1 hour" → `cron(action="add", message="...", in_seconds=3600)` (60 * 60 = 3600)
|
- "remind me in 1 hour" → `cron(action="add", message="...", in_seconds=3600)` (60 * 60 = 3600)
|
||||||
|
- **"remind me every 10 seconds for the next minute"** → `cron(action="add", message="...", every_seconds=10, in_seconds=60)` (creates 6 reminders)
|
||||||
|
- **"every 5 seconds for 30 seconds"** → `cron(action="add", message="...", every_seconds=5, in_seconds=30)` (creates 6 reminders)
|
||||||
|
|
||||||
The `in_seconds` parameter automatically computes the correct future datetime - you don't need to calculate it yourself!
|
The `in_seconds` parameter automatically computes the correct future datetime - you don't need to calculate it yourself!
|
||||||
|
|
||||||
|
|||||||
@ -71,6 +71,26 @@ web_fetch(url: str, extractMode: str = "markdown", maxChars: int = 50000) -> str
|
|||||||
- Supports markdown or plain text extraction
|
- Supports markdown or plain text extraction
|
||||||
- Output is truncated at 50,000 characters by default
|
- Output is truncated at 50,000 characters by default
|
||||||
|
|
||||||
|
## Email
|
||||||
|
|
||||||
|
### read_emails
|
||||||
|
Read emails from your configured email account via IMAP. **ALWAYS use this tool for email queries - NEVER use exec with mail commands.**
|
||||||
|
```
|
||||||
|
read_emails(limit: int = 10, unread_only: bool = False, mark_seen: bool = False) -> str
|
||||||
|
```
|
||||||
|
|
||||||
|
**CRITICAL:** For ANY question about emails (latest email, email sender, email content, etc.), you MUST use this tool. Do NOT use `exec` with `mail` command or read memory files for email information. This tool connects directly to IMAP and fetches CURRENT, real-time email data.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `limit`: Maximum number of emails to return (1-50, default: 10)
|
||||||
|
- `unread_only`: If true, only return unread emails (default: false)
|
||||||
|
- `mark_seen`: If true, mark emails as read after fetching (default: false)
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
- `read_emails(limit=1)` - Get the latest email
|
||||||
|
- `read_emails(unread_only=true)` - Get all unread emails
|
||||||
|
- `read_emails(limit=5, mark_seen=false)` - Get last 5 emails without marking as read
|
||||||
|
|
||||||
## Communication
|
## Communication
|
||||||
|
|
||||||
### message
|
### message
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user