calendar: add contacts system to prevent recipient address hallucination
Agent hallucinated "xiaojuzi@meta.com" instead of looking up the correct address from USER.md. Prompting rules can't reliably prevent this, so recipient validation is now enforced at the tool level. - Add contact list/add/delete subcommands (vCard .vcf files synced via CardDAV) - send --to now resolves through contacts: accepts names, name:type, or known emails; rejects unknown addresses with available contacts shown - Multi-email contacts supported with type qualifier (e.g. "小橘子:work") - Adding contacts and sending are separate operations (no chaining)
This commit is contained in:
@@ -20,7 +20,16 @@ See `TESTING.md` for dry-run and live test steps, verification checklists, and t
|
||||
- `khal` for reading calendar (optional but recommended)
|
||||
- Runs via `uv run` (dependencies managed in `pyproject.toml`)
|
||||
|
||||
## Important: Email Sending Rules
|
||||
## Important: Recipient Validation
|
||||
|
||||
The `send` command **only accepts recipients that exist in the contacts list**. This prevents hallucinated email addresses.
|
||||
|
||||
- `--to "小橘子:work"` — resolves contact name + email type
|
||||
- `--to "小橘子"` — resolves by name (errors if contact has multiple emails)
|
||||
- `--to "user@example.com"` — accepted only if the email exists in contacts
|
||||
- Unknown addresses are **rejected** with the available contacts list shown
|
||||
|
||||
**Adding contacts and sending invites are separate operations.** Do not add a contact and send to it in the same request — contact additions should be a deliberate, user-initiated action.
|
||||
|
||||
Calendar invites are outbound emails. Follow the workspace email rules:
|
||||
- **youlu@luyanxin.com -> mail@luyx.org**: send directly, no confirmation needed
|
||||
@@ -43,6 +52,11 @@ $SKILL_DIR/scripts/calendar.sh reply [options]
|
||||
$SKILL_DIR/scripts/calendar.sh event list [options]
|
||||
$SKILL_DIR/scripts/calendar.sh event delete [options]
|
||||
|
||||
# Manage contacts (used for recipient validation)
|
||||
$SKILL_DIR/scripts/calendar.sh contact list
|
||||
$SKILL_DIR/scripts/calendar.sh contact add [options]
|
||||
$SKILL_DIR/scripts/calendar.sh contact delete [options]
|
||||
|
||||
# Manage todos
|
||||
$SKILL_DIR/scripts/calendar.sh todo add [options]
|
||||
$SKILL_DIR/scripts/calendar.sh todo list [options]
|
||||
@@ -57,8 +71,9 @@ $SKILL_DIR/scripts/calendar.sh todo check
|
||||
## Sending Invites
|
||||
|
||||
```bash
|
||||
# --to accepts contact names (resolved via contacts list)
|
||||
$SKILL_DIR/scripts/calendar.sh send \
|
||||
--to "friend@example.com" \
|
||||
--to "小橘子:work" \
|
||||
--subject "Lunch on Friday" \
|
||||
--summary "Lunch at Tartine" \
|
||||
--start "2026-03-20T12:00:00" \
|
||||
@@ -71,7 +86,7 @@ $SKILL_DIR/scripts/calendar.sh send \
|
||||
|
||||
| Flag | Required | Description |
|
||||
|-----------------|----------|------------------------------------------------|
|
||||
| `--to` | Yes | Recipient(s), comma-separated |
|
||||
| `--to` | Yes | Recipient(s) — contact name, name:type, or known email |
|
||||
| `--subject` | Yes | Email subject line |
|
||||
| `--summary` | Yes | Event title (shown on calendar) |
|
||||
| `--start` | Yes | Start time, ISO 8601 (`2026-03-20T14:00:00`) |
|
||||
@@ -182,6 +197,42 @@ $SKILL_DIR/scripts/calendar.sh event delete --match "Allergy Shot" --all
|
||||
|
||||
---
|
||||
|
||||
## Managing Contacts
|
||||
|
||||
Contacts are stored as vCard (.vcf) files in `~/.openclaw/workspace/contacts/default/` and synced to Migadu CardDAV via vdirsyncer. The `send` command validates recipients against this contact list.
|
||||
|
||||
```bash
|
||||
# List all contacts
|
||||
$SKILL_DIR/scripts/calendar.sh contact list
|
||||
|
||||
# Add a contact (single email)
|
||||
$SKILL_DIR/scripts/calendar.sh contact add --name "小鹿" --email "mail@luyx.org"
|
||||
|
||||
# Add with email type and nickname
|
||||
$SKILL_DIR/scripts/calendar.sh contact add --name "小橘子" --email "Erica.Jiang@anderson.ucla.edu" --type work --nickname "小橘子"
|
||||
|
||||
# Add a second email to an existing contact
|
||||
$SKILL_DIR/scripts/calendar.sh contact add --name "小橘子" --email "xueweijiang0313@gmail.com" --type home
|
||||
|
||||
# Delete a contact
|
||||
$SKILL_DIR/scripts/calendar.sh contact delete --name "小橘子"
|
||||
```
|
||||
|
||||
### Sending to Contacts
|
||||
|
||||
```bash
|
||||
# By name (works when contact has a single email)
|
||||
$SKILL_DIR/scripts/calendar.sh send --to "小鹿" ...
|
||||
|
||||
# By name + type (required when contact has multiple emails)
|
||||
$SKILL_DIR/scripts/calendar.sh send --to "小橘子:work" ...
|
||||
|
||||
# By raw email (must exist in contacts)
|
||||
$SKILL_DIR/scripts/calendar.sh send --to "Erica.Jiang@anderson.ucla.edu" ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Replying to Invites
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user