@elizaos/plugin-personal-assistant 2.0.3-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +191 -0
- package/package.json +135 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shaw Walters and elizaOS Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# `@elizaos/plugin-personal-assistant`
|
|
2
|
+
|
|
3
|
+
LifeOps is the elizaOS app that runs the user's day: routines, goals,
|
|
4
|
+
calendar, email, messaging, follow-ups with people, blockers, watchers, and
|
|
5
|
+
the operational glue around them. This README is the architecture summary
|
|
6
|
+
for contributors.
|
|
7
|
+
|
|
8
|
+
## Scheduled items, not generic tasks
|
|
9
|
+
|
|
10
|
+
Every reminder, check-in, follow-up, watcher, recap, approval surface, and
|
|
11
|
+
nag-the-user-when-they-go-quiet flow is a **LifeOps scheduled item** stored
|
|
12
|
+
as a `ScheduledTask` record and owned by the runner at
|
|
13
|
+
`src/lifeops/scheduled-task/runner.ts`. There is no second LifeOps scheduling
|
|
14
|
+
mechanism.
|
|
15
|
+
|
|
16
|
+
`ScheduledTask` is intentionally not the repository-wide "task" primitive.
|
|
17
|
+
Core runtime tasks are persisted `Task` rows handled by `TaskService`; coding
|
|
18
|
+
agent work is orchestrator/task-coordinator state; project and feature tasks
|
|
19
|
+
may have their own plugin-owned records. LifeOps integrates with those
|
|
20
|
+
surfaces through public plugin/runtime contracts instead of importing or
|
|
21
|
+
owning them as LifeOps primitives.
|
|
22
|
+
|
|
23
|
+
The shape:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
interface ScheduledTask {
|
|
27
|
+
taskId: string;
|
|
28
|
+
kind: "reminder" | "checkin" | "followup" | "approval" | "recap" | "watcher" | "output" | "custom";
|
|
29
|
+
promptInstructions: string;
|
|
30
|
+
contextRequest?: { /* owner facts, entities, relationships, recent task states, event payload */ };
|
|
31
|
+
trigger: /* once | cron | interval | relative_to_anchor | during_window | event | manual | after_task */;
|
|
32
|
+
priority: "low" | "medium" | "high";
|
|
33
|
+
shouldFire?: { compose: "all" | "any" | "first_deny"; gates: Array<{ kind: string; params? }> };
|
|
34
|
+
completionCheck?: { kind: string; params?: ...; followupAfterMinutes? };
|
|
35
|
+
escalation?: { ladderKey?: string; steps?: EscalationStep[] };
|
|
36
|
+
output?: { destination: ...; target?: string; persistAs?: ... };
|
|
37
|
+
pipeline?: { onComplete?, onSkip?, onFail? };
|
|
38
|
+
subject?: { kind: "entity" | "relationship" | "thread" | "document" | "calendar_event" | "self"; id: string };
|
|
39
|
+
idempotencyKey?: string;
|
|
40
|
+
respectsGlobalPause: boolean;
|
|
41
|
+
state: ScheduledTaskState;
|
|
42
|
+
source: "default_pack" | "user_chat" | "first_run" | "plugin";
|
|
43
|
+
createdBy: string;
|
|
44
|
+
ownerVisible: boolean;
|
|
45
|
+
metadata?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The runner pattern-matches **only** on the structural fields above
|
|
50
|
+
(`kind`, `trigger`, `shouldFire`, `completionCheck`, `pipeline`, `output`,
|
|
51
|
+
`subject`, `priority`, `respectsGlobalPause`). It never inspects
|
|
52
|
+
`promptInstructions` content. This is non-negotiable.
|
|
53
|
+
|
|
54
|
+
The frozen contract is defined in `src/lifeops/scheduled-task/types.ts`
|
|
55
|
+
(the runner imports `ScheduledTask` from there). `src/lifeops/wave1-types.ts`
|
|
56
|
+
is a slightly diverged copy consumed only by the `first-run` module.
|
|
57
|
+
|
|
58
|
+
## Runtime layout
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
src/lifeops/
|
|
62
|
+
scheduled-task/ Spine: runner, state log, gate registry,
|
|
63
|
+
completion-check registry, escalation, runtime
|
|
64
|
+
wiring.
|
|
65
|
+
entities/ Entity primitive: store, merge engine, types.
|
|
66
|
+
relationships/ Relationship edges: store, observation
|
|
67
|
+
extraction, types.
|
|
68
|
+
registries/ AnchorRegistry, EventKindRegistry, FamilyRegistry,
|
|
69
|
+
BlockerRegistry, app/website blocker contributions.
|
|
70
|
+
signals/ ActivitySignalBus.
|
|
71
|
+
channels/ ChannelRegistry, priority-posture map, default
|
|
72
|
+
channel pack.
|
|
73
|
+
connectors/ ConnectorRegistry + per-connector contributions
|
|
74
|
+
(calendly, discord, duffel, google, imessage,
|
|
75
|
+
signal, telegram, twilio, whatsapp, x).
|
|
76
|
+
send-policy/ Per-connector send-policy contract + registry.
|
|
77
|
+
owner/ OwnerFactStore.
|
|
78
|
+
first-run/ FirstRunService, state store, customize
|
|
79
|
+
questions, replay.
|
|
80
|
+
pending-prompts/ PendingPromptsStore (the planner-visible
|
|
81
|
+
"questions waiting for the user" surface).
|
|
82
|
+
global-pause/ GlobalPauseStore.
|
|
83
|
+
handoff/ HandoffStore (per-room handoff state).
|
|
84
|
+
i18n/ MultilingualPromptRegistry.
|
|
85
|
+
graph-migration/ Migration into the entity/relationship graph.
|
|
86
|
+
seed-routine-migration/ Migration off legacy seed routines.
|
|
87
|
+
...other LifeOps-owned helpers (calendar, email, messaging, payments,
|
|
88
|
+
subscriptions, assistant workflows, etc.)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Default packs
|
|
92
|
+
|
|
93
|
+
Default packs are bundles of typed scheduled-item definitions compiled into
|
|
94
|
+
`ScheduledTask` records (and sometimes anchor-consolidation policies,
|
|
95
|
+
escalation ladders, autofill whitelists). LifeOps-owned packs live in
|
|
96
|
+
`src/default-packs/`:
|
|
97
|
+
|
|
98
|
+
- `daily-rhythm` — gm, gn, daily check-in.
|
|
99
|
+
- `morning-brief` — fired on `wake.confirmed`.
|
|
100
|
+
- `quiet-user-watcher` — daily watcher.
|
|
101
|
+
- `habit-starters` — eight habits, **offered** (not auto-seeded).
|
|
102
|
+
- `executive-assistant` — twenty-five scheduled records covering twenty
|
|
103
|
+
personal/executive assistant scenario families, **offered** (not auto-seeded).
|
|
104
|
+
- `inbox-triage-starter` — opt-in, gated on Gmail.
|
|
105
|
+
- `followup-starter` — watcher firing per overdue relationship.
|
|
106
|
+
- `autofill-whitelist-pack`, `consolidation-policies`, `escalation-ladders`
|
|
107
|
+
— policy-only packs.
|
|
108
|
+
|
|
109
|
+
`@elizaos/plugin-health` ships `bedtime`, `wake-up`, `sleep-recap` and
|
|
110
|
+
registers them when a health connector pairs.
|
|
111
|
+
|
|
112
|
+
### Adding a new default pack
|
|
113
|
+
|
|
114
|
+
1. Add a file under `src/default-packs/<name>.ts` that exports a
|
|
115
|
+
`DefaultPack` matching `registry-types.ts`.
|
|
116
|
+
2. Define `ReminderTaskDefinition`, `CheckInTaskDefinition`,
|
|
117
|
+
`WatcherTaskDefinition`, `ApprovalTaskDefinition`, `RecapTaskDefinition`,
|
|
118
|
+
or `OutputTaskDefinition` values and compile them with
|
|
119
|
+
`compileTaskDefinition` / `compileTaskDefinitions`. Pack files should not
|
|
120
|
+
construct raw `ScheduledTaskSeed` records.
|
|
121
|
+
3. Import and append it to `DEFAULT_PACKS` in `src/default-packs/index.ts`.
|
|
122
|
+
4. If the pack should be **auto-enabled**, list it in
|
|
123
|
+
`getDefaultEnabledPacks`. If it should be **offered** during first-run
|
|
124
|
+
customize, list it in `getOfferedDefaultPacks`. If neither, the pack
|
|
125
|
+
only seeds when invoked explicitly.
|
|
126
|
+
5. Run `bun run lint:default-packs` (also runs as `pretest`). The lint
|
|
127
|
+
rules are embedded in `scripts/lint-default-packs.mjs`. CI rejects packs
|
|
128
|
+
that violate them, including raw `ScheduledTask` construction.
|
|
129
|
+
6. Add a record-id constant export so consumers can target the records by
|
|
130
|
+
stable ID.
|
|
131
|
+
|
|
132
|
+
The runtime never seeds packs by name string-match; everything goes through
|
|
133
|
+
`getAllDefaultPacks()`.
|
|
134
|
+
|
|
135
|
+
## Knowledge graph
|
|
136
|
+
|
|
137
|
+
`EntityStore` (nodes) and `RelationshipStore` (edges) at
|
|
138
|
+
`src/lifeops/entities/` and `src/lifeops/relationships/`. The graph is
|
|
139
|
+
per-agent. The `entityId === "self"` row is bootstrapped on first use.
|
|
140
|
+
|
|
141
|
+
- **Cadence lives on the edge.** "Pat — every 14 days" is a
|
|
142
|
+
`Relationship`, not an `Entity` attribute. Cadence-bearing
|
|
143
|
+
`ScheduledTask`s use `subject.kind = "relationship"`.
|
|
144
|
+
- **Identities are observed.** `(platform, handle)` pairs route through
|
|
145
|
+
`observeIdentity`; the merge engine in `entities/merge.ts` collapses
|
|
146
|
+
entities with high-confidence identity matches. Manual merges go through
|
|
147
|
+
`POST /api/lifeops/entities/merge` and are audited.
|
|
148
|
+
- **REST surface** — routes live in `src/routes/`.
|
|
149
|
+
|
|
150
|
+
## Pause and handoff
|
|
151
|
+
|
|
152
|
+
- **Global pause** (`global-pause/store.ts`) — stops every
|
|
153
|
+
`ScheduledTask` with `respectsGlobalPause: true`. Toggleable via UI or
|
|
154
|
+
`/api/lifeops/app-state`.
|
|
155
|
+
- **Per-room handoff** (`handoff/store.ts`) — flips a multi-party room
|
|
156
|
+
into handoff after the agent says "I'll let you take it from here."
|
|
157
|
+
Typed resume conditions (`mention | explicit_resume | silence_minutes |
|
|
158
|
+
user_request_help`). The `RoomPolicyProvider` reads
|
|
159
|
+
`HandoffStore.status(roomId).active` and gates further agent
|
|
160
|
+
contributions.
|
|
161
|
+
|
|
162
|
+
## Plugin dependencies
|
|
163
|
+
|
|
164
|
+
LifeOps consumes `@elizaos/plugin-health` for sleep/circadian/health metrics,
|
|
165
|
+
screen-time action planning, health action planning, health-context formatting,
|
|
166
|
+
and health connector contributions.
|
|
167
|
+
The plugin contributes through the registries listed above (`AnchorRegistry`,
|
|
168
|
+
`ConnectorRegistry`, `FamilyRegistry`, default packs) and public factories such
|
|
169
|
+
as `createHealthActionRunner`, `createScreenTimeActionRunner`, and
|
|
170
|
+
`createHealthProvider`. LifeOps does not import directly into the health
|
|
171
|
+
internals; it consumes the plugin's public exports only. See
|
|
172
|
+
`plugins/plugin-health/README.md`.
|
|
173
|
+
|
|
174
|
+
## Cross-agent invariants
|
|
175
|
+
|
|
176
|
+
1. The runner never pattern-matches `promptInstructions`.
|
|
177
|
+
2. `subject.kind = "relationship"` for cadence-bearing tasks.
|
|
178
|
+
3. Identities are observed, not assigned.
|
|
179
|
+
4. Connectors and channels return typed `DispatchResult`. No `boolean`.
|
|
180
|
+
5. `shouldFire.gates` is always an array.
|
|
181
|
+
6. `acknowledged` ≠ `completed`. Pipeline `onComplete` only fires on
|
|
182
|
+
`completed`.
|
|
183
|
+
7. Snooze resets the escalation ladder.
|
|
184
|
+
8. Global pause skips tasks with `respectsGlobalPause: true`.
|
|
185
|
+
|
|
186
|
+
## Where to look next
|
|
187
|
+
|
|
188
|
+
- Frozen interface types: `src/lifeops/scheduled-task/types.ts`.
|
|
189
|
+
- Prompt-content lint rules: `scripts/lint-default-packs.mjs`.
|
|
190
|
+
- Health domain: `plugins/plugin-health/README.md`.
|
|
191
|
+
- REST routes: `src/routes/`.
|
package/package.json
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@elizaos/plugin-personal-assistant",
|
|
3
|
+
"version": "2.0.3-beta.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Personal-assistant orchestration plugin: BRIEF, PRIORITIZE, PERSONAL_ASSISTANT cross-domain orchestration, scheduled-task owner CRUD, and default-pack composition. Slimmed from the legacy plugin-lifeops; domain-specific surfaces have moved to plugin-inbox, plugin-goals, plugin-calendar, plugin-blocker, plugin-finances, plugin-relationships, etc.",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"./src/api/client-lifeops.ts",
|
|
8
|
+
"./dist/api/client-lifeops.js"
|
|
9
|
+
],
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
"./package.json": "./package.json",
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"eliza-source": {
|
|
16
|
+
"types": "./src/index.ts",
|
|
17
|
+
"import": "./src/index.ts",
|
|
18
|
+
"default": "./src/index.ts"
|
|
19
|
+
},
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./plugin": {
|
|
24
|
+
"types": "./dist/plugin.d.ts",
|
|
25
|
+
"eliza-source": {
|
|
26
|
+
"types": "./src/plugin.ts",
|
|
27
|
+
"import": "./src/plugin.ts",
|
|
28
|
+
"default": "./src/plugin.ts"
|
|
29
|
+
},
|
|
30
|
+
"import": "./dist/plugin.js",
|
|
31
|
+
"default": "./dist/plugin.js"
|
|
32
|
+
},
|
|
33
|
+
"./*.css": "./dist/*.css",
|
|
34
|
+
"./*": {
|
|
35
|
+
"types": "./dist/*.d.ts",
|
|
36
|
+
"eliza-source": {
|
|
37
|
+
"types": "./src/*.ts",
|
|
38
|
+
"import": "./src/*.ts",
|
|
39
|
+
"default": "./src/*.ts"
|
|
40
|
+
},
|
|
41
|
+
"import": "./dist/*.js",
|
|
42
|
+
"default": "./dist/*.js"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"lint:default-packs": "node scripts/lint-default-packs.mjs",
|
|
47
|
+
"verify": "bun run lint:default-packs && bun run build:types && bun run test",
|
|
48
|
+
"pretest": "node scripts/lint-default-packs.mjs",
|
|
49
|
+
"test": "vitest run --config vitest.config.ts",
|
|
50
|
+
"test:app-state": "vitest run --config vitest.config.ts eliza/plugins/plugin-personal-assistant/test/lifeops-app-state.test.ts",
|
|
51
|
+
"test:background-real": "vitest run --config vitest.background-real.config.ts test/scheduled-task-end-to-end.e2e.test.ts test/reminder-review-job.real.e2e.test.ts test/lifeops-scheduling.real.test.ts test/schedule-merged-state.real.test.ts",
|
|
52
|
+
"test:integration": "cd ../../.. && vitest run --config eliza/packages/test/vitest/integration.config.ts eliza/plugins/plugin-personal-assistant/test/life-smoke.integration.test.ts",
|
|
53
|
+
"test:scenarios": "cd ../.. && bun packages/scenario-runner/src/cli.ts list plugins/plugin-personal-assistant/test/scenarios",
|
|
54
|
+
"bench:work-threads": "cd ../.. && bun plugins/plugin-personal-assistant/scripts/work-thread-benchmark.ts",
|
|
55
|
+
"verify:live-schedule": "bun run ./scripts/verify-live-schedule-data.ts",
|
|
56
|
+
"build": "bun run build:js && bun run build:types",
|
|
57
|
+
"clean": "rm -rf dist",
|
|
58
|
+
"build:js": "bun run clean && tsup --config tsup.config.ts",
|
|
59
|
+
"build:types": "tsc --noCheck -p tsconfig.build.json"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@capacitor/core": "8.4.0",
|
|
63
|
+
"@elizaos/agent": "2.0.3-beta.2",
|
|
64
|
+
"@elizaos/app-core": "2.0.3-beta.2",
|
|
65
|
+
"@elizaos/capacitor-calendar": "2.0.3-beta.2",
|
|
66
|
+
"@elizaos/capacitor-mobile-signals": "2.0.3-beta.2",
|
|
67
|
+
"@elizaos/core": "2.0.3-beta.2",
|
|
68
|
+
"@elizaos/macosreminders": "2.0.3-beta.2",
|
|
69
|
+
"@elizaos/native-activity-tracker": "2.0.3-beta.2",
|
|
70
|
+
"@elizaos/plugin-blocker": "2.0.3-beta.2",
|
|
71
|
+
"@elizaos/plugin-browser": "2.0.3-beta.2",
|
|
72
|
+
"@elizaos/plugin-calendar": "2.0.3-beta.2",
|
|
73
|
+
"@elizaos/plugin-calendly": "2.0.3-beta.2",
|
|
74
|
+
"@elizaos/plugin-discord": "2.0.3-beta.2",
|
|
75
|
+
"@elizaos/plugin-elizacloud": "2.0.3-beta.2",
|
|
76
|
+
"@elizaos/plugin-finances": "2.0.3-beta.2",
|
|
77
|
+
"@elizaos/plugin-goals": "2.0.3-beta.2",
|
|
78
|
+
"@elizaos/plugin-google": "2.0.3-beta.2",
|
|
79
|
+
"@elizaos/plugin-health": "2.0.3-beta.2",
|
|
80
|
+
"@elizaos/plugin-inbox": "2.0.3-beta.2",
|
|
81
|
+
"@elizaos/plugin-phone": "2.0.3-beta.2",
|
|
82
|
+
"@elizaos/plugin-reminders": "2.0.3-beta.2",
|
|
83
|
+
"@elizaos/plugin-remote-desktop": "2.0.3-beta.2",
|
|
84
|
+
"@elizaos/plugin-scheduling": "2.0.3-beta.2",
|
|
85
|
+
"@elizaos/plugin-whatsapp": "2.0.3-beta.2",
|
|
86
|
+
"@elizaos/plugin-x": "2.0.3-beta.2",
|
|
87
|
+
"@elizaos/shared": "2.0.3-beta.2",
|
|
88
|
+
"@elizaos/ui": "2.0.3-beta.2",
|
|
89
|
+
"drizzle-orm": "0.45.2",
|
|
90
|
+
"lucide-react": "^1.0.0",
|
|
91
|
+
"react-plaid-link": "^4.0.1",
|
|
92
|
+
"sharp": "^0.34.5",
|
|
93
|
+
"zod": "^4.4.3"
|
|
94
|
+
},
|
|
95
|
+
"devDependencies": {
|
|
96
|
+
"@electric-sql/pglite": "^0.4.0",
|
|
97
|
+
"@types/jsdom": "^28.0.0",
|
|
98
|
+
"bun-types": "1.3.14",
|
|
99
|
+
"dotenv": "^17.2.3",
|
|
100
|
+
"google-auth-library": "^10.0.0",
|
|
101
|
+
"jsdom": "^29.0.0",
|
|
102
|
+
"json5": "^2.2.3",
|
|
103
|
+
"react-dom": "*",
|
|
104
|
+
"ts-morph": "28.0.0",
|
|
105
|
+
"tsup": "^8.5.1",
|
|
106
|
+
"vite": "^8.0.0",
|
|
107
|
+
"vitest": "^4.0.17"
|
|
108
|
+
},
|
|
109
|
+
"peerDependencies": {
|
|
110
|
+
"react": "*",
|
|
111
|
+
"react-dom": "*"
|
|
112
|
+
},
|
|
113
|
+
"agentConfig": {
|
|
114
|
+
"pluginType": "elizaos:plugin:1.0.0",
|
|
115
|
+
"pluginParameters": {}
|
|
116
|
+
},
|
|
117
|
+
"elizaos": {
|
|
118
|
+
"app": {
|
|
119
|
+
"heroImage": "assets/hero.png",
|
|
120
|
+
"permissions": [
|
|
121
|
+
"reminders",
|
|
122
|
+
"calendar",
|
|
123
|
+
"notes"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"publishConfig": {
|
|
128
|
+
"access": "public"
|
|
129
|
+
},
|
|
130
|
+
"types": "./dist/index.d.ts",
|
|
131
|
+
"files": [
|
|
132
|
+
"dist"
|
|
133
|
+
],
|
|
134
|
+
"gitHead": "82fe0f44215954c2417328203f5bd6510985c1fc"
|
|
135
|
+
}
|