Personal Information Manager for elizaOS β calendar, tasks, notes, and reminders for both agents AND their users.
Users can manage their schedules through natural language:
- "Remind me to call mom in 2 hours" β sets a timed reminder
- "Add a task to finish the report by Friday, high priority" β creates a prioritized to-do
- "Note: the API key is stored in vault" β saves a searchable note
- "What's on my schedule this week?" β shows events, tasks, and reminders
The agent automatically maintains its own organization:
- Follow-up tracking: When the agent commits to something ("I'll check on that"), the
PIM_FOLLOWUPevaluator creates an agent-owned task - Knowledge capture: Important information from conversations gets saved as searchable notes via the
PIM_KNOWLEDGEevaluator - Schedule awareness: The
SCHEDULEprovider shows the agent both its own tasks AND the current user's schedule - Daily journaling: When enabled, the agent reflects on its day, summarizing conversations, extracting themes, and generating insights (see Configuration)
| Feature | Description |
|---|---|
| Calendar Events | Schedule meetings, appointments, and events with date/time |
| Tasks/To-Do | GTD-style task management with priorities (1-5) and due dates |
| Notes | Semantic search-enabled note-taking |
| Reminders | Time-based notifications ("remind me in 2 hours") |
| Bookmarks | Save and organize URLs with descriptions |
| Journal | Daily diary with mood/energy tracking |
| Inbox | Quick capture for later triage (GTD-style) |
bun add @elizaos/plugin-pimAdd to your agent configuration:
import { pimPlugin } from '@elizaos/plugin-pim';
const agent = {
plugins: [pimPlugin],
// ... other config
};| Setting | Default | Description |
|---|---|---|
PIM_AGENT_ONLY |
false |
When true, disables all user-facing actions. The agent can still use PIM internally via evaluators and providers. Useful for agent self-management without user interaction. |
PIM_AGENT_DAILY_JOURNAL |
false |
When true, the agent automatically generates a reflective journal entry at the end of each day. |
PIM_JOURNAL_TIME |
23 |
Hour (0-23) when the daily journal should be generated. Default is 11pm. |
PIM_JOURNAL_MIN_MESSAGES |
10 |
Minimum number of messages required to generate a journal. Days with fewer messages are skipped. |
PIM_DEFAULT_TIMEZONE |
UTC |
Default timezone for date calculations (e.g., America/New_York) |
PIM_REMINDER_CHECK_INTERVAL |
60000 |
How often to check for due reminders (ms) |
Enable automatic daily journaling for the agent:
PIM_AGENT_DAILY_JOURNAL=true
PIM_JOURNAL_TIME=23When enabled, the agent will:
- Collect all conversations and interactions from the day
- Summarize each conversation (participants, topics, outcomes, sentiment)
- Extract themes across all conversations
- Generate a reflective journal entry with:
- Executive summary of the day
- Conversation highlights
- Challenges and learnings
- Mood and energy inference
- Focus areas for tomorrow
The journal uses a hierarchical summarization approach to handle unlimited daily volume without exceeding context limits. Each conversation is summarized independently, then all summaries are combined into the final journal.
Sample journal output:
Today was a productive day with 47 messages across 8 conversations.
The main themes were API integration issues, deployment questions, and
feature requests for the dashboard...
I noticed several users struggling with authentication flow - this might
be worth documenting better. The conversation with Alex about the caching
strategy was particularly insightful...
Tomorrow I should follow up on the unresolved database migration question
and check if Sarah's deployment succeeded.
Set PIM_AGENT_ONLY=true to run PIM as an internal-only system:
PIM_AGENT_ONLY=trueIn this mode:
- β Agent can create tasks/notes via evaluators (self-management)
- β Providers supply PIM data to the agent's context
- β Reminder worker still processes due reminders
- β Users cannot create PIM items through conversation
This is useful when you want the agent to maintain its own organization without exposing PIM functionality to users.
All PIM items are stored in the existing memories table with type='pim' in metadata. Different item types (events, tasks, notes, etc.) are distinguished by the pimType field.
Why not separate tables?
- Leverages existing Memory infrastructure (embeddings, scoping, CRUD)
- No schema migrations needed
- Simpler queries for cross-type operations ("what's on my schedule?")
- Easy to add new item types
Trade-off: Time-range queries are filtered in-memory. For most users (<1000 items), this is fine. Power users might need database indexing.
Date/time handling is split between LLM and code:
User: "Remind me tomorrow at 3pm"
β
LLM extracts: { relative: "tomorrow", time: "3pm" }
β
Code computes: 1702918800000 (UTC timestamp)
Why? LLMs are unreliable at date math. They might miscalculate days, confuse timezones, or hallucinate dates. By having the LLM extract structured components and letting code do the math, we get reliability.
Instead of creating one task per reminder (which would bloat the task table), we use a single recurring task that polls for all due reminders every 60 seconds.
Trade-off: Reminders fire within 60 seconds of their target time, not exactly on time. For personal productivity, this is acceptable.
PIM items can be owned by either the user OR the agent:
// User's items (created via actions)
entityId: message.entityId
// Agent's own items (created via evaluators)
entityId: runtime.agentIdActions create user-owned items. Evaluators create agent-owned items. The schedule provider shows both.
All items use this structure in the memories table:
{
id: UUID,
entityId: UUID, // Owner (agent or user)
agentId: UUID, // Managing agent
roomId: UUID, // Context
content: { text: string },
metadata: {
type: 'pim', // Memory system type
_v: 1, // Schema version
pimType: 'event' | 'task' | 'note' | 'reminder' | 'bookmark' | 'journal' | 'inbox',
// Type-specific fields...
}
}The _v field enables future migrations. When the schema changes:
- Increment
PIM_SCHEMA_VERSION - Add migration logic to handle old versions
Schedule meetings, appointments, and events with date/time support.
Creating events:
User: Schedule a meeting with the design team tomorrow at 2pm
Agent: β
I've scheduled "Meeting with the design team" for tomorrow at 2:00 PM.
User: Add a dentist appointment on December 20th at 10am at Main Street Dental
Agent: β
I've scheduled "Dentist appointment" for Fri, Dec 20 at 10:00 AM
π Main Street Dental
User: Set up a team standup every Monday at 9am
Agent: β
I've scheduled "Team standup" for Mon, Dec 16 at 9:00 AM
Managing events:
User: Reschedule the design meeting to 3pm
Agent: β
Updated "Meeting with the design team" β 3:00 PM
User: Cancel the dentist appointment
Agent: ποΈ Cancelled event: "Dentist appointment"
User: What's on my calendar this week?
Agent: π
**This Week**
- Mon at 9:00 AM: Team standup
- Mon at 3:00 PM: Meeting with the design team
- Wed at 2:00 PM: Project review
| Action | Trigger phrases |
|---|---|
CREATE_EVENT |
"schedule", "add event", "set up meeting", "book" |
UPDATE_EVENT |
"reschedule", "move", "change the time" |
DELETE_EVENT |
"cancel", "remove event", "delete meeting" |
GET_SCHEDULE |
"what's on my calendar", "my schedule", "upcoming events" |
GTD-style task management with priorities (1=URGENT to 5=OPTIONAL) and due dates.
Creating tasks:
User: Add a task to review the PR
Agent: β
Added task: "Review the PR" [MEDIUM]
User: I need to finish the quarterly report by Friday, it's urgent
Agent: β
Added task: "Finish the quarterly report" [URGENT]
π
Due: Fri, Dec 20
User: Add "buy groceries" to my todo list, low priority
Agent: β
Added task: "Buy groceries" [LOW]
User: Task: call the insurance company @calls
Agent: β
Added task: "Call the insurance company" [MEDIUM]
π·οΈ Context: @calls
Managing tasks:
User: Show my tasks
Agent: π **Tasks** (4)
β [URGENT] Finish quarterly report (due: in 2 days)
β [HIGH] Review the PR
β [MEDIUM] Call insurance company π·οΈ@calls
β [LOW] Buy groceries
User: What are my overdue tasks?
Agent: π **Overdue Tasks** (1)
β [HIGH] Submit expense report β οΈ 3 days ago
User: Mark the groceries task as done
Agent: β
Great job! "Buy groceries" is now complete!
User: Change the PR review priority to high
Agent: β
Updated "Review the PR" β priority: HIGH
User: Delete the insurance task
Agent: ποΈ Deleted task: "Call insurance company"
| Action | Trigger phrases |
|---|---|
CREATE_TASK |
"add task", "todo", "I need to", "don't forget" |
LIST_TASKS |
"show tasks", "my todos", "what tasks" |
UPDATE_TASK |
"change task", "update priority", "set due date" |
COMPLETE_TASK |
"mark done", "complete", "finished" |
DELETE_TASK |
"delete task", "remove todo" |
Semantic search-enabled note-taking. Notes are indexed for meaning-based retrieval.
Creating notes:
User: Note: the API endpoint is https://api.example.com/v2
Agent: π Saved note: "API endpoint"
https://api.example.com/v2
User: Save a note about the meeting - we decided to launch on March 1st
Agent: π Saved note: "Meeting decision"
We decided to launch on March 1st
User: Remember that Sarah prefers email over Slack
Agent: π Saved note: "Sarah's communication preference"
Sarah prefers email over Slack
Finding notes:
User: Find my notes about the API
Agent: π **Found 2 notes:**
**API endpoint**
https://api.example.com/v2
**Backend configuration**
API uses OAuth2, rate limit is 100 req/min
User: What did I write about the launch?
Agent: π **Found 1 note:**
**Meeting decision**
We decided to launch on March 1st
| Action | Trigger phrases |
|---|---|
CREATE_NOTE |
"note:", "save note", "remember that" |
SEARCH_NOTES |
"find notes", "search notes", "what did I write about" |
UPDATE_NOTE |
"edit note", "update the note about" |
DELETE_NOTE |
"delete note", "remove the note about" |
Time-based notifications that fire when due.
Setting reminders:
User: Remind me to call mom in 2 hours
Agent: β° Reminder set!
"Call mom"
π
Today at 5:00 PM (in 2 hours)
User: Remind me tomorrow at 9am to check the server logs
Agent: β° Reminder set!
"Check the server logs"
π
Mon, Dec 16 at 9:00 AM (in 18 hours)
User: Set a reminder for Friday to submit my timesheet
Agent: β° Reminder set!
"Submit timesheet"
π
Fri, Dec 20 at 9:00 AM (in 4 days)
Managing reminders:
User: Show my reminders
Agent: β° **Pending Reminders** (3)
β’ **Call mom**
π
Today at 5:00 PM (in 2 hours)
β’ **Check server logs**
π
Mon at 9:00 AM (in 18 hours)
β’ **Submit timesheet**
π
Fri at 9:00 AM (in 4 days)
User: Cancel the reminder about calling mom
Agent: ποΈ Cancelled reminder: "Call mom"
User: Dismiss the reminder
Agent: β
Dismissed reminder: "Check server logs"
| Action | Trigger phrases |
|---|---|
CREATE_REMINDER |
"remind me", "set reminder", "alert me", "ping me" |
LIST_REMINDERS |
"show reminders", "my reminders", "what reminders" |
DELETE_REMINDER |
"cancel reminder", "remove reminder" |
DISMISS_REMINDER |
"dismiss", "got it", "acknowledge" |
Save and organize URLs with descriptions.
Saving bookmarks:
User: Bookmark https://docs.elizaos.com - elizaOS documentation
Agent: π Saved bookmark: "elizaOS documentation"
https://docs.elizaos.com
User: Save this link: https://github.com/elizaos/eliza
Agent: π Saved bookmark: "GitHub - elizaos/eliza"
https://github.com/elizaos/eliza
Managing bookmarks:
User: Show my bookmarks
Agent: π **Bookmarks** (2)
β’ **elizaOS documentation**
https://docs.elizaos.com
β’ **GitHub - elizaos/eliza**
https://github.com/elizaos/eliza
User: Delete the documentation bookmark
Agent: ποΈ Deleted bookmark: "elizaOS documentation"
| Action | Trigger phrases |
|---|---|
SAVE_BOOKMARK |
"bookmark", "save link", "save url" |
LIST_BOOKMARKS |
"show bookmarks", "my bookmarks" |
DELETE_BOOKMARK |
"delete bookmark", "remove bookmark" |
Daily diary with optional mood and energy tracking.
Writing entries:
User: Journal: Today was productive. Finished the big feature and got good feedback.
Agent: π Journal entry saved for today
Mood: not set | Energy: not set
User: Add to my journal - feeling great today, high energy. Had a good workout.
Agent: π Journal entry updated for today
Mood: great | Energy: high
User: Dear diary, the project launch went well but I'm exhausted
Agent: π Journal entry saved for today
Mood: neutral | Energy: low
Reviewing entries:
User: Show my journal from this week
Agent: π **Journal Entries**
**Fri, Dec 13** π High energy
Today was productive. Finished the big feature...
**Thu, Dec 12** π Low energy
The project launch went well but I'm exhausted...
User: What did I write yesterday?
Agent: π **Thu, Dec 12**
The project launch went well but I'm exhausted
Mood: neutral | Energy: low
| Action | Trigger phrases |
|---|---|
JOURNAL_ENTRY |
"journal:", "diary:", "add to journal" |
GET_JOURNAL |
"show journal", "my journal", "what did I write" |
GTD-style quick capture for thoughts that need later processing.
Capturing ideas:
User: Brain dump: check out that new AI framework everyone's talking about
Agent: π₯ Captured to inbox
"Check out that new AI framework everyone's talking about"
User: Quick thought - maybe we should refactor the auth module
Agent: π₯ Captured to inbox
"Maybe we should refactor the auth module"
User: Idea: podcast episode about productivity systems
Agent: π₯ Captured to inbox
"Podcast episode about productivity systems"
Processing inbox:
User: What's in my inbox?
Agent: π₯ **Inbox** (3 items)
β’ Check out that new AI framework everyone's talking about
β’ Maybe we should refactor the auth module
β’ Podcast episode about productivity systems
User: Turn the auth module idea into a task
Agent: β
Created task from inbox item
"Refactor the auth module" [MEDIUM]
π₯ Inbox item marked as processed
User: Make the podcast idea a note
Agent: π Created note from inbox item
"Podcast episode about productivity systems"
π₯ Inbox item marked as processed
| Action | Trigger phrases |
|---|---|
CAPTURE |
"brain dump", "quick thought", "idea:", "capture" |
LIST_INBOX |
"what's in inbox", "show inbox" |
TRIAGE_INBOX |
"turn into task", "make it a note", "process inbox" |
Injects both the agent's own schedule AND the current user's schedule into context. Cached for 5 minutes.
Output includes:
- Agent's schedule: Follow-up tasks, knowledge notes, reminders the agent owns
- User's schedule: Events, tasks, reminders belonging to the current user
This dual view enables the agent to be aware of its own obligations while helping users.
Provides capability information to the agent, helping it understand what PIM actions are available.
Evaluators run after conversations to help the agent manage itself.
Extracts follow-up tasks from agent commitments. When the agent says things like:
- "I'll check on that for you"
- "Let me get back to you"
- "I'll look into this"
The evaluator creates an agent-owned task to track the follow-up.
Extracts important information from conversations and saves it as agent-owned notes. Captures:
- User preferences
- Technical context
- Project/work information
- Decisions made
These notes are semantically searchable and tagged by user/context.
The plugin emits pim:reminder_fired events when reminders become due:
interface ReminderFiredEvent {
reminder: ReminderMemory;
entityId: UUID;
roomId: UUID;
triggerTime: string; // Formatted
message: string;
}Other plugins can listen for these events to trigger notifications, messages, etc.
User preferences are stored as entity components (pim_preferences):
interface PIMPreferences {
timezone: string; // IANA timezone (e.g., 'America/New_York')
defaultReminderMinutes: number; // Default reminder before events
weekStartsOn: 0 | 1; // 0=Sunday, 1=Monday
dailyBriefingEnabled: boolean;
dailyBriefingTime?: string; // HH:MM in local time
}Here's how features work together in a typical productivity workflow:
# Morning planning
User: What's on my schedule today?
Agent: π
**Today**
- 10:00 AM: Team standup
- 2:00 PM: Design review
π **Priority Tasks**
- [URGENT] Finish quarterly report (due: today!)
- [HIGH] Review PR #42
β° **Reminders**
- In 2 hours: Call insurance company
# Quick capture during the day
User: Brain dump: look into that caching library Jake mentioned
Agent: π₯ Captured to inbox
User: Note: the design team prefers Figma over Sketch
Agent: π Saved note: "Design team tool preference"
# Task completion
User: I finished the quarterly report
Agent: β
Great job! "Finish quarterly report" is now complete!
# End of day review
User: Show my inbox
Agent: π₯ **Inbox** (3 items)
β’ Look into caching library Jake mentioned
β’ Check competitor pricing
β’ Research conference options
User: Make the caching library one a task for next week
Agent: β
Created task: "Look into caching library" [MEDIUM]
π
Due: Mon, Dec 23
# Journal reflection
User: Journal: Good day overall. Got the report done. Feeling tired but satisfied.
Agent: π Journal entry saved for today
Personal Information Managers (PIMs) are tools that help people organize their lives. Classic examples include:
- Palm Pilot β the iconic 90s handheld organizer
- Microsoft Outlook β calendar, tasks, and email in one
- Apple's suite β Notes + Reminders + Calendar working together
This plugin brings that same organizational capability to AI agents, letting them help users (or themselves) stay organized through conversation.
# Install dependencies
bun install
# Build
bun run build
# Run tests
bun run test
# Format code
bun run formatMIT