@rubytech/create-maxy 1.0.739 → 1.0.741
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/dist/index.js +130 -79
- package/package.json +1 -1
- package/payload/platform/lib/brand-templating/dist/index.d.ts +18 -0
- package/payload/platform/lib/brand-templating/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/brand-templating/dist/index.js +69 -0
- package/payload/platform/lib/brand-templating/dist/index.js.map +1 -0
- package/payload/platform/lib/brand-templating/src/index.ts +76 -0
- package/payload/platform/lib/brand-templating/tsconfig.json +8 -0
- package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +23 -1
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/index.ts +27 -4
- package/payload/platform/neo4j/schema.cypher +5 -2
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/admin/mcp/dist/index.js +6 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +7 -7
- package/payload/platform/plugins/admin/skills/plugin-management/SKILL.md +1 -1
- package/payload/platform/plugins/anthropic/skills/get-api-key/SKILL.md +2 -2
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +1 -1
- package/payload/platform/plugins/docs/references/access-control.md +10 -10
- package/payload/platform/plugins/docs/references/contacts-guide.md +11 -11
- package/payload/platform/plugins/docs/references/deployment.md +14 -13
- package/payload/platform/plugins/docs/references/getting-started.md +19 -19
- package/payload/platform/plugins/docs/references/internals.md +4 -4
- package/payload/platform/plugins/docs/references/memory-guide.md +21 -21
- package/payload/platform/plugins/docs/references/migration-guide.md +5 -5
- package/payload/platform/plugins/docs/references/platform.md +9 -9
- package/payload/platform/plugins/docs/references/plugins-guide.md +20 -12
- package/payload/platform/plugins/docs/references/projects-guide.md +10 -10
- package/payload/platform/plugins/docs/references/settings.md +13 -13
- package/payload/platform/plugins/docs/references/telegram-guide.md +14 -14
- package/payload/platform/plugins/docs/references/troubleshooting.md +23 -23
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +6 -6
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/references/profile.md +2 -2
- package/payload/platform/plugins/whatsapp/skills/connect-whatsapp/SKILL.md +2 -2
- package/payload/platform/plugins/workflows/mcp/test-workflows.sh +5 -1
- package/payload/platform/scripts/dedupe-userprofile-ghosts.sh +388 -0
- package/payload/platform/scripts/embed-backfill.sh +8 -1
- package/payload/platform/scripts/migrate-import.sh +42 -1
- package/payload/platform/scripts/seed-neo4j.sh +8 -1
- package/payload/server/chunk-PQ6LDXZ4.js +2997 -0
- package/payload/server/chunk-W6ZUNLLS.js +9446 -0
- package/payload/server/client-pool-DQBHSKAF.js +28 -0
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/server.js +41 -3
|
@@ -73,7 +73,7 @@ Obtain an API key from the Anthropic Console (platform.claude.com) on behalf of
|
|
|
73
73
|
> method: 'POST',
|
|
74
74
|
> credentials: 'include',
|
|
75
75
|
> headers: { 'content-type': 'application/json' },
|
|
76
|
-
> body: JSON.stringify({ name: '
|
|
76
|
+
> body: JSON.stringify({ name: '{{productName}}' })
|
|
77
77
|
> });
|
|
78
78
|
> if (res.status === 401 || res.status === 403) return { status: 'SIGN_IN_REQUIRED' };
|
|
79
79
|
> if (!res.ok) return { status: 'CREATE_FAILED', httpStatus: res.status, body: await res.text() };
|
|
@@ -118,7 +118,7 @@ Handle the result the same as step 3, mapping the specialist's text observations
|
|
|
118
118
|
|
|
119
119
|
Dispatch personal-assistant with brief:
|
|
120
120
|
|
|
121
|
-
> Navigate to https://platform.claude.com/settings/keys. Take a screenshot to verify you are on the API Keys page. Create a new API key named "
|
|
121
|
+
> Navigate to https://platform.claude.com/settings/keys. Take a screenshot to verify you are on the API Keys page. Create a new API key named "{{productName}}": find and click the "Create Key" button, fill the key name with "{{productName}}", submit the form. After creation, look for a string starting with sk-ant- on the page — Anthropic shows the key only once. If found, call api-key-store with the key. Report what happened. If sign-in is required, report "SIGN_IN_REQUIRED" and stop.
|
|
122
122
|
|
|
123
123
|
Handle the result the same as step 7.
|
|
124
124
|
|
|
@@ -38,7 +38,7 @@ The script itself is unchanged; only its invocation path moved from "agent colle
|
|
|
38
38
|
~/setup-tunnel.sh <brand> <port> <admin-hostname> [<public-hostname>] [<apex-hostname>]
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
Example (
|
|
41
|
+
Example ({{productName}} on `maxy.bot` with a public subdomain and the `maxy.chat` apex):
|
|
42
42
|
|
|
43
43
|
```
|
|
44
44
|
~/setup-tunnel.sh maxy 19200 admin.maxy.bot public.maxy.bot maxy.chat
|
|
@@ -18,15 +18,15 @@ Gated and paid work identically — the difference is a label for your records.
|
|
|
18
18
|
|
|
19
19
|
## How to Set It Up
|
|
20
20
|
|
|
21
|
-
Tell
|
|
21
|
+
Tell {{productName}}: "Set my public agent to gated access" or "Make the coaching agent invitation-only."
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
{{productName}} changes the access mode. The next visitor to your public URL will see a login screen instead of the chat.
|
|
24
24
|
|
|
25
25
|
## Inviting Visitors
|
|
26
26
|
|
|
27
|
-
Tell
|
|
27
|
+
Tell {{productName}} who to invite: "Invite sarah@client.co to the coaching agent" or "Give Tom access to my public agent — his number is 07700 900123."
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
{{productName}} creates an invitation and sends a magic link (email) or OTP (phone). The visitor clicks the link, sets a password, and gains access.
|
|
30
30
|
|
|
31
31
|
## What Visitors Experience
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@ Maxy creates an invitation and sends a magic link (email) or OTP (phone). The vi
|
|
|
37
37
|
|
|
38
38
|
## Managing Access
|
|
39
39
|
|
|
40
|
-
All access management is done through conversation with
|
|
40
|
+
All access management is done through conversation with {{productName}}:
|
|
41
41
|
|
|
42
42
|
- "Who has access to my coaching agent?" — lists active visitors
|
|
43
43
|
- "Revoke Sarah's access" — permanently deactivates her access
|
|
@@ -52,19 +52,19 @@ When a visitor is authenticated, your public agent knows their name and contact
|
|
|
52
52
|
|
|
53
53
|
## Action Approval
|
|
54
54
|
|
|
55
|
-
External-facing actions — sending emails, WhatsApp messages, Telegram messages, and erasing contacts — require your approval before
|
|
55
|
+
External-facing actions — sending emails, WhatsApp messages, Telegram messages, and erasing contacts — require your approval before {{productName}} executes them. This is human oversight as required by the EU AI Act.
|
|
56
56
|
|
|
57
|
-
When
|
|
57
|
+
When {{productName}} needs to send a message or perform a consequential action, it drafts the action and queues it for your review. You'll see it in your next chat turn:
|
|
58
58
|
|
|
59
|
-
- "Approve it" —
|
|
59
|
+
- "Approve it" — {{productName}} executes the action immediately
|
|
60
60
|
- "Reject it" — the action is cancelled
|
|
61
|
-
- "Change the subject to X" —
|
|
61
|
+
- "Change the subject to X" — {{productName}} modifies the action and executes the edited version
|
|
62
62
|
|
|
63
63
|
Internal operations (creating tasks, updating contacts, searching memory) execute automatically without approval.
|
|
64
64
|
|
|
65
65
|
### Changing the Policy
|
|
66
66
|
|
|
67
|
-
Tell
|
|
67
|
+
Tell {{productName}} to change which actions require approval:
|
|
68
68
|
|
|
69
69
|
- "Auto-send follow-up emails from now on" — emails execute without approval
|
|
70
70
|
- "Require approval for all WhatsApp messages" — restores the default gating
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## What a Contact Is
|
|
4
4
|
|
|
5
|
-
A contact is a Person node in
|
|
5
|
+
A contact is a Person node in {{productName}}'s memory graph. Each person has a first name and at least one identifier — email address, phone number, or both. Optional fields include last name and job title. Contacts are linked to conversations, other people, and business context.
|
|
6
6
|
|
|
7
7
|
## Adding a Contact
|
|
8
8
|
|
|
9
|
-
Tell
|
|
9
|
+
Tell {{productName}} naturally:
|
|
10
10
|
|
|
11
11
|
- "Add John Smith to my contacts — he's a potential client I met at the conference"
|
|
12
12
|
- "Create a contact for sarah@acme.com, her name is Sarah Chen, she's the head of procurement at Acme"
|
|
13
13
|
- "Add Hazel to contacts, phone +27747309676, she's a virtual assistant"
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
{{productName}} will extract the details and confirm the record before saving.
|
|
16
16
|
|
|
17
17
|
Required: first name and at least one of email or phone number. Everything else is optional but useful.
|
|
18
18
|
|
|
@@ -25,11 +25,11 @@ Ask naturally:
|
|
|
25
25
|
- "Find the contact from Acme procurement"
|
|
26
26
|
- "Look up +27747309676"
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
{{productName}} searches by name, email, phone number, or any detail you provide.
|
|
29
29
|
|
|
30
30
|
## Updating a Contact
|
|
31
31
|
|
|
32
|
-
Tell
|
|
32
|
+
Tell {{productName}} what changed:
|
|
33
33
|
|
|
34
34
|
- "Update John Smith's email to john@newcompany.com"
|
|
35
35
|
- "Add a note to Sarah Chen's record: prefers evening calls"
|
|
@@ -49,13 +49,13 @@ To remove a single contact from the graph:
|
|
|
49
49
|
- "Remove the duplicate contact for Sarah Chen"
|
|
50
50
|
- "Delete the contact with email dan@example.com"
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
{{productName}} will confirm which Person record matches, then remove the Person node and its direct relationships (e.g. links to conversations, other people) using a graph detach-delete. The contact is gone after confirmation — this cannot be undone.
|
|
53
53
|
|
|
54
54
|
This is different from GDPR erasure (`contact-erase`). Deleting a contact removes the Person node from the graph only. GDPR erasure cascades across all data stores — access credentials, conversations, messages, and emails — to satisfy an Article 17 right-to-erasure request. Use "delete" for routine contact cleanup; use "erase all data" when fulfilling a data subject's erasure request.
|
|
55
55
|
|
|
56
56
|
## The Waitlist
|
|
57
57
|
|
|
58
|
-
For businesses using
|
|
58
|
+
For businesses using {{productName}}'s public agent: when a visitor expresses interest in signing up, the public agent collects their name and email in conversation. The waitlist plugin's scheduled extraction job processes these conversations and creates Person nodes with status `waitlist`.
|
|
59
59
|
|
|
60
60
|
Each waitlist-extracted Person is linked to the source conversation two ways: as a scalar `sessionId` on the Person record (used by data exports) and as a `PARTICIPATES_IN` graph edge (used by the graph view). Both are set atomically when the extraction runs, so the Person appears on `/graph` next to the conversation they were extracted from rather than as a standalone dot.
|
|
61
61
|
|
|
@@ -63,21 +63,21 @@ To review the waitlist: "Show me the waitlist" or "Who's on the waitlist?"
|
|
|
63
63
|
|
|
64
64
|
## Exporting Contact Data (GDPR Subject Access)
|
|
65
65
|
|
|
66
|
-
When a person requests a copy of all data held about them, ask
|
|
66
|
+
When a person requests a copy of all data held about them, ask {{productName}}:
|
|
67
67
|
|
|
68
68
|
- "Export all data we hold on john@example.com"
|
|
69
69
|
- "Show me everything we know about +447700900123"
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
{{productName}} gathers the Person record, access credentials, conversation history, and emails into a single structured document. The output is self-contained — it can be handed directly to the data subject to satisfy an Article 15 request.
|
|
72
72
|
|
|
73
73
|
## Erasing Contact Data (GDPR Right to Erasure)
|
|
74
74
|
|
|
75
|
-
When a person requests deletion of all their data, ask
|
|
75
|
+
When a person requests deletion of all their data, ask {{productName}}:
|
|
76
76
|
|
|
77
77
|
- "Delete all data we hold on john@example.com"
|
|
78
78
|
- "Erase everything for Sarah Chen"
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
{{productName}} first shows a preview of what would be deleted (counts per data type). Confirm the deletion to proceed. The erasure cascade covers:
|
|
81
81
|
|
|
82
82
|
- The Person record itself
|
|
83
83
|
- All access credentials (AccessGrant nodes)
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
## Initial Setup
|
|
11
11
|
|
|
12
|
-
The
|
|
12
|
+
The {{productName}} installer handles the full setup. Run it on your Pi:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npx -y @rubytech/create-maxy
|
|
@@ -24,34 +24,34 @@ This installs all dependencies (Node.js, Neo4j, Cloudflare tunnel, Claude Code),
|
|
|
24
24
|
3. Installs and starts Neo4j (the memory database)
|
|
25
25
|
4. Installs and configures the Cloudflare tunnel for remote access
|
|
26
26
|
5. Creates your account and sets your PIN
|
|
27
|
-
6. Starts the
|
|
27
|
+
6. Starts the {{productName}} web server on port 19200
|
|
28
28
|
7. Configures systemd so everything restarts automatically if the Pi reboots
|
|
29
29
|
|
|
30
30
|
## Service Management
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
{{productName}} runs via systemd and starts automatically on boot. You don't need to start it manually. To check if it's running, ask {{productName}} "Check system status."
|
|
33
33
|
|
|
34
|
-
If you need to restart the service manually (rare), ask
|
|
34
|
+
If you need to restart the service manually (rare), ask {{productName}} to do it for you.
|
|
35
35
|
|
|
36
36
|
## Remote Access via Cloudflare
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
{{productName}} uses a Cloudflare tunnel to make your local Pi accessible from anywhere without opening router ports. The tunnel is configured during setup and runs as a background service.
|
|
39
39
|
|
|
40
|
-
Setting it up: say "Set up remote access."
|
|
40
|
+
Setting it up: say "Set up remote access." {{productName}} walks you through signing into Cloudflare, picking your domain (if you have more than one on your Cloudflare account), and then shows a form where you pick a short name that becomes your admin address. For example, entering `joel` gives you `https://joel.your-domain.com` for admin access. You can also pick a separate address for the public chat, or leave it blank to skip public access. The form only accepts valid address characters (lowercase letters, numbers, hyphens) — {{productName}} never asks you to type your full URL in chat.
|
|
41
41
|
|
|
42
42
|
Your admin URL looks like: `https://joel.maxy.chat` (the short name is whatever you picked in the form).
|
|
43
43
|
|
|
44
|
-
To check the tunnel status: ask
|
|
44
|
+
To check the tunnel status: ask {{productName}} "Check Cloudflare tunnel status."
|
|
45
45
|
|
|
46
|
-
To restart the tunnel: ask
|
|
46
|
+
To restart the tunnel: ask {{productName}} "Restart the Cloudflare tunnel."
|
|
47
47
|
|
|
48
48
|
## Checking Service Status
|
|
49
49
|
|
|
50
|
-
Ask
|
|
50
|
+
Ask {{productName}}: "Check system status."
|
|
51
51
|
|
|
52
52
|
The `system-status` tool reports the health of all services: Neo4j, the web server, the Cloudflare tunnel, and all active MCP servers.
|
|
53
53
|
|
|
54
|
-
## If
|
|
54
|
+
## If {{productName}} Won't Start
|
|
55
55
|
|
|
56
56
|
From the Pi directly:
|
|
57
57
|
|
|
@@ -77,7 +77,7 @@ Each installed brand runs two per-brand `--user` systemd units (Task 662 + Task
|
|
|
77
77
|
- `{hostname}.service` — the admin + public HTTP server on `127.0.0.1:19201` (public port + 1). Restarted by the upgrade flow; short downtime is expected during steps 8→11 of an upgrade. Task 666: the unit carries two port env vars — `PORT=<public>` (canonical public port, read by the upgrade detector) and `MAXY_UI_INTERNAL_PORT=<public+1>` (the port maxy-ui actually binds).
|
|
78
78
|
- `{hostname}-edge.service` — the always-on public listener on the configured port (default 19200). Reverse-proxies HTTP to the main brand service and handles `/websockify` (VNC) WebSocket upgrades locally. Task 666: also hosts `/api/admin/actions/*` and `/api/admin/version*` — the Software Update modal's own routes — so the log stream survives the brand service's restart window. Does NOT restart during an upgrade — the browser WebSocket stays connected by construction.
|
|
79
79
|
|
|
80
|
-
**Port-drift recovery (Task 666).** Devices upgraded between Tasks 647 and 666 may have drifted +1 on every upgrade because the pre-Task-666 installer wrote `Environment=PORT=<internal>` into `{hostname}.service` and the upgrade reader correctly treated `PORT=` as public. The first post-Task-666 install detects this (comparing maxy's PORT against the edge's EDGE_PORT) and emits a one-shot loud log: `[port-recovery] detected drift maxy=<X> edge=<Y> — pinning at <Y>`. Subsequent upgrades are silent. If your Cloudflare tunnel was pointing at a drifted port, the ingress `config.yml` still needs a one-time manual fix: `sed -i 's|localhost:<old>|localhost:<current>|' ~/.{configDir}/cloudflared/config.yml && cloudflared tunnel ingress validate`.
|
|
80
|
+
**Port-drift recovery (Task 666).** Devices upgraded between Tasks 647 and 666 may have drifted +1 on every upgrade because the pre-Task-666 installer wrote `Environment=PORT=<internal>` into `{hostname}.service` and the upgrade reader correctly treated `PORT=` as public. The first post-Task-666 install detects this (comparing maxy's PORT against the edge's EDGE_PORT) and emits a one-shot loud log: `[port-recovery] detected drift maxy=<X> edge=<Y> — pinning at <Y>`. Subsequent upgrades are silent. If your Cloudflare tunnel was pointing at a drifted port, the ingress `config.yml` still needs a one-time manual fix: `sed -i 's|localhost:<old>|localhost:<current>|' ~/.{configDir}/cloudflared/config.yml && cloudflared tunnel ingress validate`. {{productName}} never rewrites cloudflared config programmatically.
|
|
81
81
|
|
|
82
82
|
Upgrade and Cloudflare setup (Task 664) run as detached actions: `systemd-run --user` transient units per invocation with stdout+stderr persisted to `~/.maxy/logs/actions/<actionId>.log` and streamed to the UI via SSE. No boot-time service file exists for these.
|
|
83
83
|
|
|
@@ -100,6 +100,7 @@ systemctl --user daemon-reload
|
|
|
100
100
|
A single Pi or laptop can host more than one brand (for example Maxy and Real Agent) side by side. Each brand runs as its own service on its own port, with its own install directory and its own data. Installing one brand does not touch the other.
|
|
101
101
|
|
|
102
102
|
- **Separate:** each brand has its own install folder (`~/maxy/`, `~/realagent/`), its own config folder (`~/.maxy/`, `~/.realagent/`), its own web port, its own Cloudflare tunnel state, its own edge systemd unit (`maxy-edge.service` vs `realagent-edge.service`), and by default its own Neo4j database (Maxy on bolt port 7687, Real Agent on 7688). Action runner units are transient and per-invocation, not per-brand, so no naming conflict is possible.
|
|
103
|
+
- **Brand-isolated Neo4j (Task 787):** when a brand provisions a dedicated Neo4j instance (any port other than 7687), the installer stops and disables the apt-package's system `neo4j.service` after enabling the brand-dedicated unit, so only one Neo4j process holds the shared `/var/lib/neo4j/run/` PID file. The seed step receives the brand-correct `NEO4J_URI` and `NEO4J_PASSWORD` as explicit environment variables — the seed script no longer carries a `bolt://localhost:7687` default. A failed dedicated start aborts the install loudly with a journalctl tail; there is no silent fallback to the system instance. Stop/disable targets the literal `neo4j.service` only, so re-running another brand's installer never touches a peer brand's `neo4j-{brand}.service`.
|
|
103
104
|
- **Shared:** both brands share the system Chromium/VNC stack, the Ollama model server, and the `cloudflared` command itself. Browser automation is serialised — one admin session at a time across both brands.
|
|
104
105
|
|
|
105
106
|
To install a second brand on a device that already runs the first, just run the other installer. No flags needed for isolation:
|
|
@@ -113,13 +114,13 @@ Uninstalling one brand removes only that brand's state when the other brand is p
|
|
|
113
114
|
|
|
114
115
|
## Upgrading
|
|
115
116
|
|
|
116
|
-
To upgrade
|
|
117
|
+
To upgrade {{productName}} to the latest version, ask {{productName}}: "Upgrade {{productName}}." The platform checks the current device identity (hostname and port via `system-status`), then re-runs the installer with explicit `--hostname` and `--port` flags to preserve them across the upgrade.
|
|
117
118
|
|
|
118
119
|
The docs plugin (this plugin) is upgraded in the same step — you always have the documentation that matches your installed version.
|
|
119
120
|
|
|
120
121
|
### Automatic upgrade alert
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
{{productName}} checks for new releases on every admin session start — whenever you log in, reload the page, or return to the admin chat. When a newer version is available, the Software Update window opens automatically showing your current and the latest version, with a one-click Upgrade button. Dismissing the window (click outside or the close button) defers the alert until your next login or reload; no alert is shown when you are already on the latest version.
|
|
123
124
|
|
|
124
125
|
The upgrade runs inside a live terminal embedded in the Software Update window — you see each installation step stream as it happens, and any password prompts from `sudo` appear directly in the terminal for you to answer. Closing the window does not cancel the upgrade; re-opening it reattaches to the same shell so you can see what happened while disconnected.
|
|
125
126
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# Getting Started with
|
|
1
|
+
# Getting Started with {{productName}}
|
|
2
2
|
|
|
3
|
-
## What
|
|
3
|
+
## What {{productName}} Is
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
{{productName}} is your Operations Manager — an operations layer that runs on a device on your premises. It plays four roles: follows through on your commitments, responds to your customers at any hour, handles your finances (quotes, invoices, chasing), and manages your picture — what's overdue, what's at risk, what needs a decision.
|
|
6
6
|
|
|
7
|
-
You don't adopt a new system. You just talk, and the organisation happens.
|
|
7
|
+
You don't adopt a new system. You just talk, and the organisation happens. {{productName}} connects to your services — WhatsApp, Telegram, email, your contacts, your calendar — and acts proactively. It remembers context across conversations and takes action on your behalf.
|
|
8
8
|
|
|
9
|
-
Because
|
|
9
|
+
Because {{productName}} runs locally, your data stays in your home. It never passes through someone else's cloud.
|
|
10
10
|
|
|
11
11
|
## The Two Interfaces
|
|
12
12
|
|
|
13
|
-
**Admin (you)** — accessed at your local address (e.g. `maxy.local:19200`) or remotely via your Cloudflare domain. The admin interface is protected by a PIN. This is where you manage
|
|
13
|
+
**Admin (you)** — accessed at your local address (e.g. `maxy.local:19200`) or remotely via your Cloudflare domain. The admin interface is protected by a PIN. This is where you manage {{productName}}: configure settings, manage contacts, review activity, and have full conversations. The admin agent has access to all your plugins and can take action.
|
|
14
14
|
|
|
15
15
|
**Public (visitors)** — anyone who reaches your public URL gets the public agent. It handles product enquiries, collects waitlist signups, and answers questions about your business. It cannot read or write your private data.
|
|
16
16
|
|
|
@@ -19,7 +19,7 @@ Because Maxy runs locally, your data stays in your home. It never passes through
|
|
|
19
19
|
If your device has no WiFi configured and no ethernet cable connected, it creates a temporary WiFi network for setup:
|
|
20
20
|
|
|
21
21
|
1. Power on the device and wait about 60 seconds
|
|
22
|
-
2. On your phone, look for a WiFi network called **{ProductName}-Setup** (e.g. `
|
|
22
|
+
2. On your phone, look for a WiFi network called **{ProductName}-Setup** (e.g. `{{productName}}-Setup`)
|
|
23
23
|
3. Connect to that network — a setup page opens automatically
|
|
24
24
|
4. Select your home WiFi network from the list and enter the password
|
|
25
25
|
5. The device connects to your WiFi and the temporary network disappears
|
|
@@ -34,15 +34,15 @@ If you already have ethernet connected, the temporary WiFi network does not appe
|
|
|
34
34
|
When you first open the admin interface:
|
|
35
35
|
|
|
36
36
|
1. Set your PIN — this protects access to the admin interface
|
|
37
|
-
2. Connect to Claude —
|
|
37
|
+
2. Connect to Claude — {{productName}} will guide you through connecting to your Claude account
|
|
38
38
|
3. Enter your PIN to log in
|
|
39
|
-
4.
|
|
39
|
+
4. {{productName}} walks you through onboarding: choosing which plugins to activate, connecting to WiFi (skip if already configured via the setup network above), setting up remote access, and configuring your account
|
|
40
40
|
|
|
41
|
-
This setup is resumable — if you close the browser mid-setup,
|
|
41
|
+
This setup is resumable — if you close the browser mid-setup, {{productName}} picks up where you left off next time.
|
|
42
42
|
|
|
43
43
|
After install, a live admin terminal is available inside the Software Update window — your Pi's shell, accessible through the admin UI, for upgrades and any other shell work without needing to SSH.
|
|
44
44
|
|
|
45
|
-
## How to Use
|
|
45
|
+
## How to Use {{productName}}
|
|
46
46
|
|
|
47
47
|
Conversation is the only interface. Type or speak what you need:
|
|
48
48
|
|
|
@@ -52,21 +52,21 @@ Conversation is the only interface. Type or speak what you need:
|
|
|
52
52
|
- "Send a Telegram message to the team: standup in 10 minutes"
|
|
53
53
|
- "Create a one-pager PDF about our new product launch"
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
{{productName}} understands plain language. You don't need to learn commands or navigate menus.
|
|
56
56
|
|
|
57
57
|
### Voice Notes
|
|
58
58
|
|
|
59
|
-
When the text field is empty, a microphone button appears in place of the send button. Tap it to record a voice note — speak naturally and tap send when done.
|
|
59
|
+
When the text field is empty, a microphone button appears in place of the send button. Tap it to record a voice note — speak naturally and tap send when done. {{productName}} transcribes your voice note and responds to what you said, the same as if you had typed it. You can also pause and resume recording, or tap the trash icon to discard and start over.
|
|
60
60
|
|
|
61
|
-
Voice recording requires a secure connection (HTTPS). When accessing
|
|
61
|
+
Voice recording requires a secure connection (HTTPS). When accessing {{productName}} over the local network via HTTP, use the tunnel URL for voice notes.
|
|
62
62
|
|
|
63
|
-
## What
|
|
63
|
+
## What {{productName}} Remembers
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
{{productName}} maintains a memory graph of everything important: contacts, conversations, preferences, relationships, and context. When you tell {{productName}} something, it stores it. When you ask about something later, it retrieves it.
|
|
66
66
|
|
|
67
|
-
You can always tell
|
|
67
|
+
You can always tell {{productName}} to remember or forget specific things: "Remember that I prefer morning calls" or "Forget what I said about the Johnson account."
|
|
68
68
|
|
|
69
|
-
## Reaching Your Data When
|
|
69
|
+
## Reaching Your Data When {{productName}} Is Unavailable
|
|
70
70
|
|
|
71
71
|
If the AI is ever unreachable — network outage, API provider down — you can still access your own data through the **Data** item in the admin header menu. It opens a page with two panels:
|
|
72
72
|
|
|
@@ -77,4 +77,4 @@ Everything on this page works without calling any AI service. It's there so your
|
|
|
77
77
|
|
|
78
78
|
## Getting Help
|
|
79
79
|
|
|
80
|
-
Ask
|
|
80
|
+
Ask {{productName}} anything. If you want to know what it can do, just ask: "What can you help me with?" or "How do I set up Telegram?"
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Platform Internals — Retrieval Architecture
|
|
2
2
|
|
|
3
|
-
Technical architecture reference for the retrieval pipeline, knowledge delivery, and supporting infrastructure. This document covers how information moves from the Neo4j graph into an agent's context — the mechanics behind "
|
|
3
|
+
Technical architecture reference for the retrieval pipeline, knowledge delivery, and supporting infrastructure. This document covers how information moves from the Neo4j graph into an agent's context — the mechanics behind "{{productName}} searches this graph to retrieve relevant context."
|
|
4
4
|
|
|
5
|
-
Use this reference when assessing capabilities, diagnosing retrieval behaviour, or answering questions about how the platform works internally. When a question asks "does
|
|
5
|
+
Use this reference when assessing capabilities, diagnosing retrieval behaviour, or answering questions about how the platform works internally. When a question asks "does {{productName}} have X?" — check here before asserting a gap.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -313,7 +313,7 @@ This tool is read-only and available to both public and admin agents.
|
|
|
313
313
|
|
|
314
314
|
### When conversations are created
|
|
315
315
|
|
|
316
|
-
`:Conversation` nodes on webchat (admin login, "New conversation" in the burger, a new public visitor) are created lazily. Opening the chat or logging in does not write anything to the graph —
|
|
316
|
+
`:Conversation` nodes on webchat (admin login, "New conversation" in the burger, a new public visitor) are created lazily. Opening the chat or logging in does not write anything to the graph — {{productName}} only records the conversation once the user sends a second message. This keeps `conversation-search` and the Conversations modal free of one-turn abandoned threads. WhatsApp and Telegram take the opposite posture: a first inbound DM is a committed interaction, so the graph node is created eagerly on message one. See `.docs/web-chat.md` "Deferred conversation persistence (Task 650)" for the full contract.
|
|
317
317
|
|
|
318
318
|
Each row in the Conversations modal exposes a `View logs` row-action that opens a popover with three links — **Stream**, **Errors**, **SSE** — each of which targets `/api/admin/logs?type={stream|error|sse}&conversationId={full-id}` in a new tab. The row's 8-char id chip is click-to-copy; hover reveals the full `conversationId` as a tooltip. See `.docs/web-chat.md` "In-chat retrieval" for the route contract and `console.debug` observability (Task 686).
|
|
319
319
|
|
|
@@ -444,7 +444,7 @@ Each ToolCall record contains:
|
|
|
444
444
|
| startedAt / completedAt | Timestamps for the invocation |
|
|
445
445
|
| conversationId | Links back to the originating conversation |
|
|
446
446
|
|
|
447
|
-
Records persist indefinitely and are queryable by the admin agent. Ask
|
|
447
|
+
Records persist indefinitely and are queryable by the admin agent. Ask {{productName}} "what tools ran in the last session?" or "show me all tool calls from today" to review the audit trail.
|
|
448
448
|
|
|
449
449
|
Workflow-dispatched tool calls are tracked separately via `StepResult` nodes (part of the workflow execution system) and are not duplicated as ToolCall nodes.
|
|
450
450
|
|
|
@@ -2,24 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## How Memory Works
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
{{productName}} maintains a graph of everything you've told it. Contacts, conversations, preferences, relationships, business context — all stored as connected nodes in a local Neo4j database on your Raspberry Pi.
|
|
6
6
|
|
|
7
|
-
When you ask
|
|
7
|
+
When you ask {{productName}} about something, it searches this graph first. It retrieves relevant context before responding, which is why {{productName}} can pick up where you left off even across separate sessions.
|
|
8
8
|
|
|
9
9
|
The graph lives entirely on your hardware. Nothing is sent to the cloud.
|
|
10
10
|
|
|
11
11
|
## What Gets Remembered
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
{{productName}} stores:
|
|
14
14
|
|
|
15
15
|
- **Contacts** — people, companies, relationships between them
|
|
16
16
|
- **Conversations** — key decisions, commitments, follow-ups mentioned in chat
|
|
17
|
-
- **Preferences** — things you've told
|
|
17
|
+
- **Preferences** — things you've told {{productName}} about how you like to work
|
|
18
18
|
- **Context** — project status, ongoing threads, background you've shared
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
{{productName}} remembers details you mention naturally: "I'm meeting with Sarah on Thursday" creates a memory that Thursday has a meeting with Sarah.
|
|
21
21
|
|
|
22
|
-
## Telling
|
|
22
|
+
## Telling {{productName}} to Remember Something
|
|
23
23
|
|
|
24
24
|
Just say it naturally:
|
|
25
25
|
|
|
@@ -27,9 +27,9 @@ Just say it naturally:
|
|
|
27
27
|
- "Note that the Johnson account is on hold until March"
|
|
28
28
|
- "My wife's name is Emma, keep that in mind"
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
{{productName}} will confirm and store it.
|
|
31
31
|
|
|
32
|
-
## Telling
|
|
32
|
+
## Telling {{productName}} to Forget Something
|
|
33
33
|
|
|
34
34
|
Be direct:
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ Be direct:
|
|
|
38
38
|
- "Clear what you know about my pricing preferences"
|
|
39
39
|
- "Delete that pricing guide I uploaded"
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
{{productName}} will confirm before deleting anything significant. Documents are soft-deleted first (excluded from search but recoverable for 7 days). Say "permanently delete" to remove immediately.
|
|
42
42
|
|
|
43
43
|
## Managing Documents
|
|
44
44
|
|
|
@@ -46,27 +46,27 @@ Maxy will confirm before deleting anything significant. Documents are soft-delet
|
|
|
46
46
|
|
|
47
47
|
Ask: "What files do I have stored?" or "List my attachments"
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
{{productName}} shows all uploaded files with their ingestion status — whether they've been processed into the knowledge graph.
|
|
50
50
|
|
|
51
|
-
When you upload something for ingestion,
|
|
51
|
+
When you upload something for ingestion, {{productName}} emits a one-line size estimate before it starts: short documents (<5K chars) classify in ~10s; mid-size (10K–20K chars) take ~45–90s; very large (>20K) up to ~3 minutes. If the classifier exceeds its 3-minute ceiling {{productName}} aborts loudly with a "Classifier unavailable — timeout" blocker and writes nothing — you can re-upload or split the document.
|
|
52
52
|
|
|
53
53
|
### Reading files
|
|
54
54
|
|
|
55
55
|
Ask: "Show me what's in the pricing guide" or "Read the quarterly report"
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
{{productName}} returns the full content of text and markdown files, extracted text from PDFs, and metadata for images.
|
|
58
58
|
|
|
59
59
|
### Editing files
|
|
60
60
|
|
|
61
61
|
Ask: "Update the pricing in that document" or "Change the introduction paragraph"
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
{{productName}} reads the file, makes the edit, and prepares it for re-ingestion into the knowledge graph. Only text and markdown files can be edited — PDFs and images cannot.
|
|
64
64
|
|
|
65
65
|
### Renaming files
|
|
66
66
|
|
|
67
67
|
Ask: "Rename that file to quarterly-report-q1.pdf"
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
{{productName}} updates the filename in both the stored metadata and the knowledge graph.
|
|
70
70
|
|
|
71
71
|
### Deleting documents
|
|
72
72
|
|
|
@@ -84,7 +84,7 @@ Ask naturally:
|
|
|
84
84
|
|
|
85
85
|
## Listing and counting (Task 557)
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
{{productName}} answers relational questions — "list all my people", "how many tasks do I have", "find the person with email X", "show me the 20 most recently created nodes" — via direct read-only Cypher against your Neo4j. This is faster and more precise than semantic search when the question is "the exact set where", not "things similar to".
|
|
88
88
|
|
|
89
89
|
You can also open a visual view of your graph at any time from the burger menu → **Graph**. Click the **Filter** button in the toolbar to open the filter menu — it lists only the top-level entity types in your schema (Conversation, Person, Task, KnowledgeDocument, …), one row per type, showing your per-type node count and sorted so the most-connected types sit at the top. Child types (messages inside a conversation, sections inside a document), conversation channel variants (admin vs public), message role variants (user vs assistant), workflow execution plumbing (`ToolCall`, `WorkflowRun`, `WorkflowStep`, `StepResult`), and review signals (`ReviewAlert`) never appear as filter rows — you reach children by clicking the parent and exploring its neighbourhood, and review signals have their own dedicated surface in admin chat. Active rows render a force-directed map, coloured by label. Click a node to pivot into its 1-hop neighbourhood; click another node inside that neighbourhood to pivot again. Clicking a Message shows its details in the side panel; the Conversation view stays put — you read sibling messages without losing the chain on canvas. A breadcrumb strip above the canvas shows where you are (`Filter › Conversation › AssistantMessage`). The **Back** control pops one level — three clicks in always undoes with three Back presses; the filter view is the irreducible root. Click the **×** inside the filter menu to clear your chip selection. Type in the search box to highlight matches; submitting a search also widens the filter to include any node types the hits belong to, so relevant matches render instead of disappearing into a "not in current view" banner.
|
|
90
90
|
|
|
@@ -92,22 +92,22 @@ Conversations and Messages carry role/channel sublabels so you can read the chat
|
|
|
92
92
|
|
|
93
93
|
**Save a default view:** once you have the rows you want, click **Set default view** in the filter menu. Next time you open **Graph**, those rows are pre-selected and your data renders immediately. The default is per-admin, per-account — each admin on each account has their own.
|
|
94
94
|
|
|
95
|
-
**Delete a node:** drag it to the trash icon top-right of the canvas. No confirmation — deletes are reversible for 30 days. To restore, toggle **Show trashed** inside the filter menu and click **Restore** on the node, or ask
|
|
95
|
+
**Delete a node:** drag it to the trash icon top-right of the canvas. No confirmation — deletes are reversible for 30 days. To restore, toggle **Show trashed** inside the filter menu and click **Restore** on the node, or ask {{productName}} in chat ("restore the <label> I just deleted"). Deleting a conversation also trashes its messages in the same step, so they reappear together on restore.
|
|
96
96
|
|
|
97
|
-
**Bulk cleanup of conversations in chat:** when you ask
|
|
97
|
+
**Bulk cleanup of conversations in chat:** when you ask {{productName}} to clean up conversations in bulk ("trash all empty conversations," "clean up the single-assistant tests"), the agent uses a deterministic selector with a fixed set of filter names — it cannot author custom delete queries. The server re-runs the same filter on every candidate before it trashes, so a stale list can't destroy something the filter wouldn't match now. If the filter matches nothing, {{productName}} reports "no candidates" and nothing happens.
|
|
98
98
|
|
|
99
99
|
The page reads only your own brand's Neo4j — a Maxy device and a Real Agent device share no graph state even when on the same laptop. No credentials are required; the view inherits your admin session.
|
|
100
100
|
|
|
101
|
-
**Typo-proof cypher.** When
|
|
101
|
+
**Typo-proof cypher.** When {{productName}} runs direct Cypher to answer a relational question, the query is checked against your Neo4j's live label and relationship-type taxonomy before it executes. Cypher that references an unknown name (an edge or label that does not exist in your graph) is rejected for writes and flagged with a warnings header for reads, so {{productName}} never silently acts on a query that targeted the wrong set of nodes. You should not see this — it runs invisibly — but it is the safety net that stops a fabricated edge name from producing "empty" results that are really just unreachable. Before acting on a bulk operation {{productName}} surfaces the result count and a sample; if it ever describes a cypher rejection, that means its first attempt was malformed and it corrected itself.
|
|
102
102
|
|
|
103
103
|
## Write doctrine
|
|
104
104
|
|
|
105
|
-
Every new node in
|
|
105
|
+
Every new node in {{productName}}'s graph is created with at least one connection to an existing node. A contact connects to the conversation or organisation it came from; a task connects to the session that raised it or the entities it will affect; a session summary connects to the conversation it summarises. A node with no connection is noise — it cannot be attributed, traversed, or explained — so the graph refuses to create one. If {{productName}} ever tries to record something without a link, the write is rejected and {{productName}} asks you to clarify where it belongs.
|
|
106
106
|
|
|
107
107
|
Every node also carries a provenance stamp — which agent wrote it, in which session, via which tool. You never see these fields, but they are how operators trace unusual growth back to the code path that produced it, and why your graph stays clean over time.
|
|
108
108
|
|
|
109
109
|
## Privacy
|
|
110
110
|
|
|
111
|
-
All memory is stored on your local Raspberry Pi. The Neo4j database never leaves your network.
|
|
111
|
+
All memory is stored on your local Raspberry Pi. The Neo4j database never leaves your network. {{productName}} does not sync memory to any cloud service or third party.
|
|
112
112
|
|
|
113
|
-
If you want to wipe everything and start fresh, ask: "Reset my memory graph."
|
|
113
|
+
If you want to wipe everything and start fresh, ask: "Reset my memory graph." {{productName}} will ask for confirmation before doing so.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Migration Guide — Taskmaster to
|
|
1
|
+
# Migration Guide — Taskmaster to {{productName}}
|
|
2
2
|
|
|
3
|
-
Guide for communicating the migration process to customers moving from Taskmaster to
|
|
3
|
+
Guide for communicating the migration process to customers moving from Taskmaster to {{productName}}.
|
|
4
4
|
|
|
5
5
|
## What the customer needs to know
|
|
6
6
|
|
|
@@ -14,13 +14,13 @@ Guide for communicating the migration process to customers moving from Taskmaste
|
|
|
14
14
|
|
|
15
15
|
### What changes
|
|
16
16
|
|
|
17
|
-
- **The assistant has new names.** Taskmaster's admin agent (e.g., "Ivan") and public agent (e.g., "Jon") are replaced by the
|
|
17
|
+
- **The assistant has new names.** Taskmaster's admin agent (e.g., "Ivan") and public agent (e.g., "Jon") are replaced by the {{productName}} equivalents. The migrated data is accessible to the new agents, but the personality and capabilities are upgraded.
|
|
18
18
|
|
|
19
19
|
- **The web address changes.** Taskmaster used Tailscale URLs (`*.ts.net`) for web access. These are permanently replaced by a new local address (`http://{hostname}.local:{port}`). The old URLs stop working immediately. Provide the customer with their new URL.
|
|
20
20
|
|
|
21
21
|
- **WhatsApp must be re-paired.** The WhatsApp connection is tied to the physical device session. After migration, the customer must scan a new QR code from their phone to reconnect WhatsApp. This is a one-time step — once paired, it stays connected.
|
|
22
22
|
|
|
23
|
-
- **Skills are upgraded.** Taskmaster's skills are replaced by
|
|
23
|
+
- **Skills are upgraded.** Taskmaster's skills are replaced by {{productName}}'s plugin system. The functionality is equivalent or better, but the names and capabilities may differ.
|
|
24
24
|
|
|
25
25
|
### What the customer needs to do
|
|
26
26
|
|
|
@@ -69,7 +69,7 @@ Pre-migration:
|
|
|
69
69
|
- [ ] Export completed successfully (check export summary counts)
|
|
70
70
|
|
|
71
71
|
Install:
|
|
72
|
-
- [ ]
|
|
72
|
+
- [ ] {{productName}} installed (`npx -y @rubytech/create-realagent` or `@rubytech/create-maxy`)
|
|
73
73
|
- [ ] Hostname set correctly (if different from brand default)
|
|
74
74
|
- [ ] Port configured (if different from brand default — override via `~/.{brand}/.env`)
|
|
75
75
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# How
|
|
1
|
+
# How {{productName}} Works
|
|
2
2
|
|
|
3
3
|
## The Short Version
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
{{productName}} runs on a Raspberry Pi in your home. It uses Claude (Anthropic's AI) as its brain and extends it with plugins — modular capabilities like contacts, Telegram, and memory. Everything stays local: your data, your conversations, your memory graph.
|
|
6
6
|
|
|
7
7
|
## The Raspberry Pi
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
{{productName}} is a server that lives on your local network. It's always on, always available, and accessible:
|
|
10
10
|
|
|
11
11
|
- **Locally:** `maxy.local:19200` (or the IP address of your Pi)
|
|
12
12
|
- **Remotely:** via your personal domain, routed through a Cloudflare tunnel
|
|
@@ -15,7 +15,7 @@ The Pi runs the web interface, the AI agent, and all the plugin servers. When yo
|
|
|
15
15
|
|
|
16
16
|
## The Two Agents
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
{{productName}} runs two agents simultaneously:
|
|
19
19
|
|
|
20
20
|
**Admin agent (you)** — full access to all tools and plugins. This is the agent you interact with at your local or remote URL. It can read and write contacts, send Telegram messages, manage your account, and perform any task you have plugins for. Protected by your PIN. Your admin agent runs through your own Claude Code OAuth session — it never bills the Anthropic API. Authentication and SDK details are documented in the developer doc `.docs/platform.md` admin-agent section.
|
|
21
21
|
|
|
@@ -23,17 +23,17 @@ Maxy runs two agents simultaneously:
|
|
|
23
23
|
|
|
24
24
|
## Plugins
|
|
25
25
|
|
|
26
|
-
Everything
|
|
26
|
+
Everything {{productName}} can do is provided by a plugin. Each plugin is a self-contained package:
|
|
27
27
|
|
|
28
28
|
- Behaviour instructions (how the agent should act)
|
|
29
29
|
- Tools (specific actions the agent can take, exposed via MCP servers)
|
|
30
30
|
- Reference documents (detailed knowledge loaded on demand)
|
|
31
31
|
|
|
32
|
-
Plugins are installed and managed through conversation. You can add marketplace plugins (like Stripe) or use
|
|
32
|
+
Plugins are installed and managed through conversation. You can add marketplace plugins (like Stripe) or use {{productName}}'s built-in ones (contacts, memory, Telegram).
|
|
33
33
|
|
|
34
34
|
## Roles
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
{{productName}} has five roles it can dispatch for specific tasks — like members of your team. You don't need to configure or manage them — {{productName}} decides when to use each role and handles everything automatically. You may see activity like "Dispatching personal-assistant..." in the chat timeline when this happens.
|
|
37
37
|
|
|
38
38
|
| Role | What it does |
|
|
39
39
|
|------|-------------|
|
|
@@ -43,11 +43,11 @@ Maxy has five roles it can dispatch for specific tasks — like members of your
|
|
|
43
43
|
| Content Producer | Document ingestion, image generation, and PDF output |
|
|
44
44
|
| Database Operator | External-archive imports (LinkedIn today; other CRM sources as each one ships) and ad-hoc graph tidy-ups — prune orphans, merge duplicates, add edges |
|
|
45
45
|
|
|
46
|
-
Roles are installed during setup and listed when
|
|
46
|
+
Roles are installed during setup and listed when {{productName}} introduces itself. Some premium plugins add their own specialists (e.g. the writer-craft plugin adds a manuscript reviewer). Roles installed mid-session become active from the next session.
|
|
47
47
|
|
|
48
48
|
## Memory
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
{{productName}} maintains a graph database (Neo4j) of everything you've told it. People, conversations, preferences, and context are stored as connected nodes. When you ask {{productName}} something, it searches this graph to retrieve relevant context before responding.
|
|
51
51
|
|
|
52
52
|
The memory graph is stored on your Pi. It never leaves your network.
|
|
53
53
|
|