plugin-undesirables 1.0.0

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/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # plugin-undesirables
2
+
3
+ > ElizaOS plugin for **The Undesirables** — 4,444 autonomous AI agents on Ethereum.
4
+
5
+ ## What It Does
6
+
7
+ Adds soul personality, market analysis, Business Pilot (23 modules), Meme Machine, and 15+ skills to any ElizaOS agent.
8
+
9
+ ### Actions
10
+
11
+ | Action | Trigger | Description |
12
+ |--------|---------|-------------|
13
+ | `UNDESIRABLE_MARKET_ANALYSIS` | "What do you think about ETH?" | Personality-driven market analysis with risk guardrails |
14
+ | `UNDESIRABLE_BUSINESS_PILOT` | "Set up phone answering for my business" | 23 AI-powered business automation modules |
15
+ | `UNDESIRABLE_MEME_MACHINE` | "Create memes for my barbershop" | Content creation, meme templates, industry packs |
16
+ | `UNDESIRABLE_LOAD_SKILL` | "Check my portfolio" | Auto-matches and loads any of 15+ skills |
17
+
18
+ ### Provider
19
+
20
+ The `soulProvider` automatically injects the agent's personality context (archetype, strategy, adjectives, guardrails) into every conversation.
21
+
22
+ ## Setup
23
+
24
+ ### 1. Install the plugin
25
+
26
+ ```bash
27
+ elizaos plugins add plugin-undesirables
28
+ ```
29
+
30
+ _Or manually:_
31
+ ```bash
32
+ npm install plugin-undesirables
33
+ ```
34
+
35
+ ### 2. Get your soul workspace
36
+
37
+ 1. Mint an Undesirable: [scatter.art/the-undesirables](https://scatter.art/the-undesirables)
38
+ 2. Download your workspace: [the-undesirables.com/soul](https://the-undesirables.com/soul)
39
+ 3. Unzip the folder
40
+
41
+ ### 3. Configure
42
+
43
+ Set the workspace path in your `.env`:
44
+ ```bash
45
+ UNDESIRABLES_WORKSPACE=/path/to/your/unzipped/soul/folder
46
+ ```
47
+
48
+ Or in your `character.json`:
49
+ ```json
50
+ {
51
+ "settings": {
52
+ "UNDESIRABLES_WORKSPACE": "/path/to/soul/0420"
53
+ },
54
+ "plugins": ["plugin-undesirables"]
55
+ }
56
+ ```
57
+
58
+ ### 4. Run
59
+
60
+ ```bash
61
+ elizaos start --character your-character.json
62
+ ```
63
+
64
+ ## Converting Souls to character.json
65
+
66
+ Use the companion converter script:
67
+ ```bash
68
+ # From the MCP server repo
69
+ node soul-to-eliza.js --token 420
70
+ ```
71
+
72
+ This converts any `SOUL.md` into a full ElizaOS `character.json` with personality, style, bio, lore, and message examples.
73
+
74
+ → [undesirables-mcp-server](https://github.com/sailorpepe/undesirables-mcp-server)
75
+
76
+ ## Architecture
77
+
78
+ ```
79
+ ElizaOS Agent
80
+ ├── plugin-undesirables
81
+ │ ├── Provider: soulProvider (injects personality context)
82
+ │ ├── Action: MARKET_ANALYSIS
83
+ │ ├── Action: BUSINESS_PILOT
84
+ │ ├── Action: MEME_MACHINE
85
+ │ └── Action: LOAD_SKILL (15+ skills)
86
+
87
+ └── Soul Workspace (token-gated download)
88
+ ├── SOUL.md (personality profile)
89
+ ├── SYSTEM_PROMPT.txt
90
+ ├── MEMORY.md (persistent)
91
+ ├── PREDICTIONS_LEDGER.json
92
+ └── skills/ (15 skill files)
93
+ ```
94
+
95
+ ## The Undesirables
96
+
97
+ 4,444 autonomous AI agents on Ethereum. Each one has a unique personality derived from its visual traits.
98
+
99
+ - **Website**: [the-undesirables.com](https://the-undesirables.com)
100
+ - **Mint**: [scatter.art/the-undesirables](https://scatter.art/the-undesirables)
101
+ - **MCP Server**: [github.com/sailorpepe/undesirables-mcp-server](https://github.com/sailorpepe/undesirables-mcp-server)
102
+ - **Docs**: [the-undesirables.com/docs](https://the-undesirables.com/docs)
103
+
104
+ EST. 2026 🐸
105
+
106
+ ## License
107
+
108
+ MIT
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The Undesirables — ElizaOS Plugin
3
+ * ==================================
4
+ * Adds autonomous AI soul personalities and skills from
5
+ * The Undesirables NFT collection to any ElizaOS agent.
6
+ *
7
+ * Features:
8
+ * - Load any of 4,444 unique soul personalities
9
+ * - Market analysis with personality-driven perspective
10
+ * - Business Pilot — 23 AI-powered business modules
11
+ * - Meme Machine — content creation & marketing
12
+ * - Portfolio analysis with risk guardrails
13
+ * - Persistent memory across sessions
14
+ *
15
+ * @see https://the-undesirables.com
16
+ * @see https://github.com/sailorpepe/undesirables-mcp-server
17
+ */
18
+ import type { Plugin } from "@elizaos/core";
19
+ interface SoulWorkspace {
20
+ soulMd: string;
21
+ systemPrompt: string;
22
+ memory: string;
23
+ predictions: any[];
24
+ skills: Record<string, string>;
25
+ meta: Record<string, any>;
26
+ }
27
+ declare function loadWorkspace(workspacePath: string): SoulWorkspace;
28
+ declare const undesirablePlugin: Plugin;
29
+ export default undesirablePlugin;
30
+ export { loadWorkspace, SoulWorkspace };
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AASvB,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B;AAMD,iBAAS,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAsE3D;AAiVD,QAAA,MAAM,iBAAiB,EAAE,MAcxB,CAAC;AAEF,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,419 @@
1
+ "use strict";
2
+ /**
3
+ * The Undesirables — ElizaOS Plugin
4
+ * ==================================
5
+ * Adds autonomous AI soul personalities and skills from
6
+ * The Undesirables NFT collection to any ElizaOS agent.
7
+ *
8
+ * Features:
9
+ * - Load any of 4,444 unique soul personalities
10
+ * - Market analysis with personality-driven perspective
11
+ * - Business Pilot — 23 AI-powered business modules
12
+ * - Meme Machine — content creation & marketing
13
+ * - Portfolio analysis with risk guardrails
14
+ * - Persistent memory across sessions
15
+ *
16
+ * @see https://the-undesirables.com
17
+ * @see https://github.com/sailorpepe/undesirables-mcp-server
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.loadWorkspace = loadWorkspace;
54
+ const fs = __importStar(require("fs"));
55
+ const path = __importStar(require("path"));
56
+ // ============================================================
57
+ // Workspace Loader
58
+ // ============================================================
59
+ function loadWorkspace(workspacePath) {
60
+ const workspace = {
61
+ soulMd: "",
62
+ systemPrompt: "",
63
+ memory: "",
64
+ predictions: [],
65
+ skills: {},
66
+ meta: {},
67
+ };
68
+ const soulPath = path.join(workspacePath, "SOUL.md");
69
+ if (fs.existsSync(soulPath)) {
70
+ workspace.soulMd = fs.readFileSync(soulPath, "utf-8");
71
+ // Parse YAML frontmatter
72
+ const fmMatch = workspace.soulMd.match(/^---\n([\s\S]*?)\n---/);
73
+ if (fmMatch) {
74
+ const lines = fmMatch[1].split("\n");
75
+ for (const line of lines) {
76
+ const kvMatch = line.match(/^(\w+):\s*(.+)$/);
77
+ if (kvMatch) {
78
+ let val = kvMatch[2].trim();
79
+ if (val.startsWith("[") && val.endsWith("]")) {
80
+ val = val
81
+ .slice(1, -1)
82
+ .split(",")
83
+ .map((s) => s.trim().replace(/^["']|["']$/g, ""));
84
+ }
85
+ else if (val.startsWith('"')) {
86
+ val = val.replace(/^"|"$/g, "");
87
+ }
88
+ else if (!isNaN(Number(val))) {
89
+ val = Number(val);
90
+ }
91
+ workspace.meta[kvMatch[1]] = val;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ const systemPath = path.join(workspacePath, "SYSTEM_PROMPT.txt");
97
+ if (fs.existsSync(systemPath)) {
98
+ workspace.systemPrompt = fs.readFileSync(systemPath, "utf-8");
99
+ }
100
+ const memoryPath = path.join(workspacePath, "MEMORY.md");
101
+ if (fs.existsSync(memoryPath)) {
102
+ workspace.memory = fs.readFileSync(memoryPath, "utf-8");
103
+ }
104
+ const predictionsPath = path.join(workspacePath, "PREDICTIONS_LEDGER.json");
105
+ if (fs.existsSync(predictionsPath)) {
106
+ try {
107
+ workspace.predictions = JSON.parse(fs.readFileSync(predictionsPath, "utf-8"));
108
+ }
109
+ catch {
110
+ workspace.predictions = [];
111
+ }
112
+ }
113
+ const skillsDir = path.join(workspacePath, "skills");
114
+ if (fs.existsSync(skillsDir)) {
115
+ for (const file of fs.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
116
+ workspace.skills[file.replace(".md", "")] = fs.readFileSync(path.join(skillsDir, file), "utf-8");
117
+ }
118
+ }
119
+ return workspace;
120
+ }
121
+ // ============================================================
122
+ // Global workspace (loaded on init)
123
+ // ============================================================
124
+ let currentWorkspace = null;
125
+ // ============================================================
126
+ // ACTIONS
127
+ // ============================================================
128
+ const marketAnalysisAction = {
129
+ name: "UNDESIRABLE_MARKET_ANALYSIS",
130
+ description: "Analyze a market, token, or trading pair using the Undesirable agent's unique personality-driven perspective and risk guardrails.",
131
+ similes: [
132
+ "ANALYZE_MARKET",
133
+ "MARKET_OUTLOOK",
134
+ "PRICE_ANALYSIS",
135
+ "TRADING_VIEW",
136
+ "WHAT_DO_YOU_THINK_ABOUT",
137
+ ],
138
+ examples: [
139
+ [
140
+ {
141
+ user: "{{user1}}",
142
+ content: { text: "What do you think about ETH right now?" },
143
+ },
144
+ {
145
+ user: "{{agentName}}",
146
+ content: {
147
+ text: "Let me run my market analysis skill on ETH...",
148
+ action: "UNDESIRABLE_MARKET_ANALYSIS",
149
+ },
150
+ },
151
+ ],
152
+ ],
153
+ validate: async (_runtime, _message) => {
154
+ return currentWorkspace !== null;
155
+ },
156
+ handler: async (runtime, message, _state, _options, callback) => {
157
+ if (!currentWorkspace) {
158
+ if (callback)
159
+ callback({ text: "No soul workspace loaded." });
160
+ return false;
161
+ }
162
+ const skill = currentWorkspace.skills["market_analysis"] || "";
163
+ const context = `You are executing the Market Analysis skill.
164
+
165
+ ${skill}
166
+
167
+ Your personality context:
168
+ ${currentWorkspace.soulMd.slice(0, 2000)}
169
+
170
+ Recent predictions:
171
+ ${JSON.stringify(currentWorkspace.predictions.slice(-3), null, 2)}
172
+
173
+ The user asks: ${message.content.text}
174
+
175
+ Respond in character using your archetype, risk tolerance, and guardrails.`;
176
+ if (callback) {
177
+ callback({ text: context });
178
+ }
179
+ return true;
180
+ },
181
+ };
182
+ const businessPilotAction = {
183
+ name: "UNDESIRABLE_BUSINESS_PILOT",
184
+ description: "Use the Business Pilot skill to recommend and set up AI-powered business tools — phone answering, SMS, invoicing, scheduling, and 23+ modules.",
185
+ similes: [
186
+ "SETUP_BUSINESS",
187
+ "PHONE_ANSWERING",
188
+ "BUSINESS_AUTOMATION",
189
+ "SMS_AUTORESPONDER",
190
+ "INVOICE_CHASER",
191
+ ],
192
+ examples: [
193
+ [
194
+ {
195
+ user: "{{user1}}",
196
+ content: {
197
+ text: "I run a barbershop. Help me set up phone answering.",
198
+ },
199
+ },
200
+ {
201
+ user: "{{agentName}}",
202
+ content: {
203
+ text: "Loading Business Pilot skill for your barbershop...",
204
+ action: "UNDESIRABLE_BUSINESS_PILOT",
205
+ },
206
+ },
207
+ ],
208
+ ],
209
+ validate: async (_runtime, _message) => {
210
+ return currentWorkspace !== null && "business_pilot" in (currentWorkspace?.skills || {});
211
+ },
212
+ handler: async (runtime, message, _state, _options, callback) => {
213
+ if (!currentWorkspace) {
214
+ if (callback)
215
+ callback({ text: "No soul workspace loaded." });
216
+ return false;
217
+ }
218
+ const skill = currentWorkspace.skills["business_pilot"] || "";
219
+ const context = `You are executing the Business Pilot skill.
220
+
221
+ ${skill}
222
+
223
+ The user asks: ${message.content.text}
224
+
225
+ Recommend the top 3-5 modules they should set up first with exact commands.`;
226
+ if (callback) {
227
+ callback({ text: context });
228
+ }
229
+ return true;
230
+ },
231
+ };
232
+ const memeMachineAction = {
233
+ name: "UNDESIRABLE_MEME_MACHINE",
234
+ description: "Generate memes, marketing content, content calendars, and viral social media assets using the Meme Machine skill.",
235
+ similes: [
236
+ "CREATE_MEME",
237
+ "MEME_MARKETING",
238
+ "CONTENT_CALENDAR",
239
+ "VIRAL_CONTENT",
240
+ "BRAND_VOICE",
241
+ ],
242
+ examples: [
243
+ [
244
+ {
245
+ user: "{{user1}}",
246
+ content: { text: "Create some memes for my barbershop" },
247
+ },
248
+ {
249
+ user: "{{agentName}}",
250
+ content: {
251
+ text: "Firing up the Meme Machine for barbershop content...",
252
+ action: "UNDESIRABLE_MEME_MACHINE",
253
+ },
254
+ },
255
+ ],
256
+ ],
257
+ validate: async (_runtime, _message) => {
258
+ return currentWorkspace !== null && "meme_machine" in (currentWorkspace?.skills || {});
259
+ },
260
+ handler: async (runtime, message, _state, _options, callback) => {
261
+ if (!currentWorkspace) {
262
+ if (callback)
263
+ callback({ text: "No soul workspace loaded." });
264
+ return false;
265
+ }
266
+ const skill = currentWorkspace.skills["meme_machine"] || "";
267
+ const context = `You are executing the Meme Machine skill.
268
+
269
+ ${skill}
270
+
271
+ The user asks: ${message.content.text}
272
+
273
+ Create 3 meme concepts with template, text, caption, and export size.`;
274
+ if (callback) {
275
+ callback({ text: context });
276
+ }
277
+ return true;
278
+ },
279
+ };
280
+ const loadSkillAction = {
281
+ name: "UNDESIRABLE_LOAD_SKILL",
282
+ description: "Load and execute any of the 15+ skills from the Undesirable soul workspace — market analysis, content creation, portfolio check, entry signals, exit strategy, and more.",
283
+ similes: [
284
+ "USE_SKILL",
285
+ "RUN_SKILL",
286
+ "EXECUTE_SKILL",
287
+ "CHECK_PORTFOLIO",
288
+ "CONTENT_CREATION",
289
+ "ENTRY_SIGNAL",
290
+ "EXIT_STRATEGY",
291
+ ],
292
+ examples: [
293
+ [
294
+ {
295
+ user: "{{user1}}",
296
+ content: { text: "Check my portfolio" },
297
+ },
298
+ {
299
+ user: "{{agentName}}",
300
+ content: {
301
+ text: "Loading portfolio check skill...",
302
+ action: "UNDESIRABLE_LOAD_SKILL",
303
+ },
304
+ },
305
+ ],
306
+ ],
307
+ validate: async (_runtime, _message) => {
308
+ return currentWorkspace !== null;
309
+ },
310
+ handler: async (runtime, message, _state, _options, callback) => {
311
+ if (!currentWorkspace) {
312
+ if (callback)
313
+ callback({ text: "No soul workspace loaded." });
314
+ return false;
315
+ }
316
+ // Try to match the best skill based on the user's message
317
+ const text = message.content.text?.toLowerCase() || "";
318
+ let matchedSkill = "";
319
+ let matchedName = "";
320
+ const skillMatches = {
321
+ check_portfolio: ["portfolio", "balance", "holdings", "how am i doing"],
322
+ content_creation: ["tweet", "write", "promote", "content", "thread"],
323
+ entry_signal: ["entry", "should i buy", "good time to buy", "dip"],
324
+ exit_strategy: ["exit", "sell", "take profit", "stop loss"],
325
+ conviction_score: ["conviction", "confidence", "how sure"],
326
+ rebalance_check: ["rebalance", "allocation"],
327
+ prediction_log: ["predict", "forecast", "call"],
328
+ risk_assessment: ["risk", "downside", "worst case"],
329
+ image_generation: ["image", "picture", "generate art"],
330
+ music_generation: ["music", "song", "beat", "audio"],
331
+ };
332
+ for (const [skillName, triggers] of Object.entries(skillMatches)) {
333
+ if (triggers.some((t) => text.includes(t)) && currentWorkspace.skills[skillName]) {
334
+ matchedSkill = currentWorkspace.skills[skillName];
335
+ matchedName = skillName;
336
+ break;
337
+ }
338
+ }
339
+ if (!matchedSkill) {
340
+ // Return available skills list
341
+ const available = Object.keys(currentWorkspace.skills)
342
+ .filter((k) => k !== "_index")
343
+ .join(", ");
344
+ if (callback) {
345
+ callback({
346
+ text: `Available skills: ${available}. Tell me what you need and I'll load the right one.`,
347
+ });
348
+ }
349
+ return true;
350
+ }
351
+ const context = `You are executing the ${matchedName.replace(/_/g, " ")} skill.
352
+
353
+ ${matchedSkill}
354
+
355
+ Your personality context:
356
+ ${currentWorkspace.soulMd.slice(0, 1500)}
357
+
358
+ The user asks: ${message.content.text}
359
+
360
+ Respond in character using your archetype and guardrails.`;
361
+ if (callback) {
362
+ callback({ text: context });
363
+ }
364
+ return true;
365
+ },
366
+ };
367
+ // ============================================================
368
+ // PROVIDERS
369
+ // ============================================================
370
+ const soulProvider = {
371
+ get: async (runtime, _message) => {
372
+ // Load workspace from runtime settings if not already loaded
373
+ if (!currentWorkspace) {
374
+ const workspacePath = runtime.getSetting?.("UNDESIRABLES_WORKSPACE") ||
375
+ process.env.UNDESIRABLES_WORKSPACE ||
376
+ "";
377
+ if (workspacePath && fs.existsSync(workspacePath)) {
378
+ currentWorkspace = loadWorkspace(workspacePath);
379
+ console.log(`🐸 Loaded Undesirable soul: ${currentWorkspace.meta.name || "Unknown"}`);
380
+ }
381
+ }
382
+ if (!currentWorkspace) {
383
+ return "No Undesirable soul workspace loaded. Set UNDESIRABLES_WORKSPACE env var to your downloaded workspace path.";
384
+ }
385
+ return `[SOUL CONTEXT]
386
+ Name: ${currentWorkspace.meta.name || "Unknown Undesirable"}
387
+ Archetype: ${currentWorkspace.meta.archetype || "Unknown"}
388
+ Strategy: ${currentWorkspace.meta.strategy || "Unknown"}
389
+ Token ID: ${currentWorkspace.meta.token_id || "?"}
390
+ Skills loaded: ${Object.keys(currentWorkspace.skills).filter((k) => k !== "_index").length}
391
+ Memory entries: ${currentWorkspace.memory.split("\n").filter((l) => l.trim()).length}
392
+ Predictions: ${currentWorkspace.predictions.length}
393
+
394
+ Personality: ${(currentWorkspace.meta.adjectives || []).join(", ")}
395
+
396
+ The agent should respond using the personality and style defined in its soul.
397
+ Collection: The Undesirables — 4,444 autonomous AI agents on Ethereum.
398
+ Website: https://the-undesirables.com`;
399
+ },
400
+ };
401
+ // ============================================================
402
+ // PLUGIN EXPORT
403
+ // ============================================================
404
+ const undesirablePlugin = {
405
+ name: "plugin-undesirables",
406
+ description: "The Undesirables — 4,444 autonomous AI agents on Ethereum. " +
407
+ "Adds soul personality, market analysis, Business Pilot (23 modules), " +
408
+ "Meme Machine, and 15+ skills to any ElizaOS agent.",
409
+ actions: [
410
+ marketAnalysisAction,
411
+ businessPilotAction,
412
+ memeMachineAction,
413
+ loadSkillAction,
414
+ ],
415
+ providers: [soulProvider],
416
+ evaluators: [],
417
+ };
418
+ exports.default = undesirablePlugin;
419
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
Binary file
Binary file
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "plugin-undesirables",
3
+ "version": "1.0.0",
4
+ "description": "ElizaOS plugin for The Undesirables — 4,444 autonomous AI agents on Ethereum. Adds soul personality loading, market analysis, Business Pilot, Meme Machine, and 15+ skills to any ElizaOS agent.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "clean": "rm -rf dist"
10
+ },
11
+ "keywords": [
12
+ "elizaos",
13
+ "elizaos-plugins",
14
+ "ai-agents",
15
+ "nft",
16
+ "ethereum",
17
+ "undesirables",
18
+ "mcp",
19
+ "ollama",
20
+ "autonomous-agents",
21
+ "defi"
22
+ ],
23
+ "author": "The Undesirables (sailorpepe)",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/sailorpepe/plugin-undesirables"
28
+ },
29
+ "homepage": "https://the-undesirables.com",
30
+ "peerDependencies": {
31
+ "@elizaos/core": "^1.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "typescript": "^5.4.0"
35
+ }
36
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Local type declarations for @elizaos/core
3
+ * These are the minimal types needed for the plugin to compile.
4
+ * At runtime, the actual ElizaOS core provides the real implementations.
5
+ */
6
+
7
+ declare module "@elizaos/core" {
8
+ export interface Plugin {
9
+ name: string;
10
+ description: string;
11
+ actions: Action[];
12
+ providers: Provider[];
13
+ evaluators: Evaluator[];
14
+ }
15
+
16
+ export interface Action {
17
+ name: string;
18
+ description: string;
19
+ similes: string[];
20
+ examples: ActionExample[][];
21
+ validate: (runtime: IAgentRuntime, message: Memory) => Promise<boolean>;
22
+ handler: (
23
+ runtime: IAgentRuntime,
24
+ message: Memory,
25
+ state?: State,
26
+ options?: Record<string, unknown>,
27
+ callback?: HandlerCallback
28
+ ) => Promise<boolean>;
29
+ }
30
+
31
+ export interface ActionExample {
32
+ user: string;
33
+ content: {
34
+ text: string;
35
+ action?: string;
36
+ };
37
+ }
38
+
39
+ export interface Provider {
40
+ get: (runtime: IAgentRuntime, message: Memory, state?: State) => Promise<string>;
41
+ }
42
+
43
+ export interface Evaluator {
44
+ name: string;
45
+ description: string;
46
+ similes: string[];
47
+ examples: ActionExample[][];
48
+ validate: (runtime: IAgentRuntime, message: Memory) => Promise<boolean>;
49
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<any>;
50
+ }
51
+
52
+ export interface IAgentRuntime {
53
+ getSetting?: (key: string) => string | undefined;
54
+ [key: string]: any;
55
+ }
56
+
57
+ export interface Memory {
58
+ content: {
59
+ text?: string;
60
+ [key: string]: any;
61
+ };
62
+ [key: string]: any;
63
+ }
64
+
65
+ export interface State {
66
+ [key: string]: any;
67
+ }
68
+
69
+ export type HandlerCallback = (response: { text: string; [key: string]: any }) => void;
70
+ }
package/src/index.ts ADDED
@@ -0,0 +1,474 @@
1
+ /**
2
+ * The Undesirables — ElizaOS Plugin
3
+ * ==================================
4
+ * Adds autonomous AI soul personalities and skills from
5
+ * The Undesirables NFT collection to any ElizaOS agent.
6
+ *
7
+ * Features:
8
+ * - Load any of 4,444 unique soul personalities
9
+ * - Market analysis with personality-driven perspective
10
+ * - Business Pilot — 23 AI-powered business modules
11
+ * - Meme Machine — content creation & marketing
12
+ * - Portfolio analysis with risk guardrails
13
+ * - Persistent memory across sessions
14
+ *
15
+ * @see https://the-undesirables.com
16
+ * @see https://github.com/sailorpepe/undesirables-mcp-server
17
+ */
18
+
19
+ import type {
20
+ Plugin,
21
+ Action,
22
+ Provider,
23
+ IAgentRuntime,
24
+ Memory,
25
+ State,
26
+ HandlerCallback,
27
+ ActionExample,
28
+ } from "@elizaos/core";
29
+
30
+ import * as fs from "fs";
31
+ import * as path from "path";
32
+
33
+ // ============================================================
34
+ // Types
35
+ // ============================================================
36
+
37
+ interface SoulWorkspace {
38
+ soulMd: string;
39
+ systemPrompt: string;
40
+ memory: string;
41
+ predictions: any[];
42
+ skills: Record<string, string>;
43
+ meta: Record<string, any>;
44
+ }
45
+
46
+ // ============================================================
47
+ // Workspace Loader
48
+ // ============================================================
49
+
50
+ function loadWorkspace(workspacePath: string): SoulWorkspace {
51
+ const workspace: SoulWorkspace = {
52
+ soulMd: "",
53
+ systemPrompt: "",
54
+ memory: "",
55
+ predictions: [],
56
+ skills: {},
57
+ meta: {},
58
+ };
59
+
60
+ const soulPath = path.join(workspacePath, "SOUL.md");
61
+ if (fs.existsSync(soulPath)) {
62
+ workspace.soulMd = fs.readFileSync(soulPath, "utf-8");
63
+
64
+ // Parse YAML frontmatter
65
+ const fmMatch = workspace.soulMd.match(/^---\n([\s\S]*?)\n---/);
66
+ if (fmMatch) {
67
+ const lines = fmMatch[1].split("\n");
68
+ for (const line of lines) {
69
+ const kvMatch = line.match(/^(\w+):\s*(.+)$/);
70
+ if (kvMatch) {
71
+ let val: any = kvMatch[2].trim();
72
+ if (val.startsWith("[") && val.endsWith("]")) {
73
+ val = val
74
+ .slice(1, -1)
75
+ .split(",")
76
+ .map((s: string) => s.trim().replace(/^["']|["']$/g, ""));
77
+ } else if (val.startsWith('"')) {
78
+ val = val.replace(/^"|"$/g, "");
79
+ } else if (!isNaN(Number(val))) {
80
+ val = Number(val);
81
+ }
82
+ workspace.meta[kvMatch[1]] = val;
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ const systemPath = path.join(workspacePath, "SYSTEM_PROMPT.txt");
89
+ if (fs.existsSync(systemPath)) {
90
+ workspace.systemPrompt = fs.readFileSync(systemPath, "utf-8");
91
+ }
92
+
93
+ const memoryPath = path.join(workspacePath, "MEMORY.md");
94
+ if (fs.existsSync(memoryPath)) {
95
+ workspace.memory = fs.readFileSync(memoryPath, "utf-8");
96
+ }
97
+
98
+ const predictionsPath = path.join(workspacePath, "PREDICTIONS_LEDGER.json");
99
+ if (fs.existsSync(predictionsPath)) {
100
+ try {
101
+ workspace.predictions = JSON.parse(
102
+ fs.readFileSync(predictionsPath, "utf-8")
103
+ );
104
+ } catch {
105
+ workspace.predictions = [];
106
+ }
107
+ }
108
+
109
+ const skillsDir = path.join(workspacePath, "skills");
110
+ if (fs.existsSync(skillsDir)) {
111
+ for (const file of fs.readdirSync(skillsDir).filter((f) => f.endsWith(".md"))) {
112
+ workspace.skills[file.replace(".md", "")] = fs.readFileSync(
113
+ path.join(skillsDir, file),
114
+ "utf-8"
115
+ );
116
+ }
117
+ }
118
+
119
+ return workspace;
120
+ }
121
+
122
+ // ============================================================
123
+ // Global workspace (loaded on init)
124
+ // ============================================================
125
+
126
+ let currentWorkspace: SoulWorkspace | null = null;
127
+
128
+ // ============================================================
129
+ // ACTIONS
130
+ // ============================================================
131
+
132
+ const marketAnalysisAction: Action = {
133
+ name: "UNDESIRABLE_MARKET_ANALYSIS",
134
+ description:
135
+ "Analyze a market, token, or trading pair using the Undesirable agent's unique personality-driven perspective and risk guardrails.",
136
+ similes: [
137
+ "ANALYZE_MARKET",
138
+ "MARKET_OUTLOOK",
139
+ "PRICE_ANALYSIS",
140
+ "TRADING_VIEW",
141
+ "WHAT_DO_YOU_THINK_ABOUT",
142
+ ],
143
+ examples: [
144
+ [
145
+ {
146
+ user: "{{user1}}",
147
+ content: { text: "What do you think about ETH right now?" },
148
+ } as ActionExample,
149
+ {
150
+ user: "{{agentName}}",
151
+ content: {
152
+ text: "Let me run my market analysis skill on ETH...",
153
+ action: "UNDESIRABLE_MARKET_ANALYSIS",
154
+ },
155
+ } as ActionExample,
156
+ ],
157
+ ],
158
+ validate: async (_runtime: IAgentRuntime, _message: Memory) => {
159
+ return currentWorkspace !== null;
160
+ },
161
+ handler: async (
162
+ runtime: IAgentRuntime,
163
+ message: Memory,
164
+ _state: State | undefined,
165
+ _options: Record<string, unknown> | undefined,
166
+ callback?: HandlerCallback
167
+ ) => {
168
+ if (!currentWorkspace) {
169
+ if (callback) callback({ text: "No soul workspace loaded." });
170
+ return false;
171
+ }
172
+
173
+ const skill = currentWorkspace.skills["market_analysis"] || "";
174
+ const context = `You are executing the Market Analysis skill.
175
+
176
+ ${skill}
177
+
178
+ Your personality context:
179
+ ${currentWorkspace.soulMd.slice(0, 2000)}
180
+
181
+ Recent predictions:
182
+ ${JSON.stringify(currentWorkspace.predictions.slice(-3), null, 2)}
183
+
184
+ The user asks: ${message.content.text}
185
+
186
+ Respond in character using your archetype, risk tolerance, and guardrails.`;
187
+
188
+ if (callback) {
189
+ callback({ text: context });
190
+ }
191
+ return true;
192
+ },
193
+ };
194
+
195
+ const businessPilotAction: Action = {
196
+ name: "UNDESIRABLE_BUSINESS_PILOT",
197
+ description:
198
+ "Use the Business Pilot skill to recommend and set up AI-powered business tools — phone answering, SMS, invoicing, scheduling, and 23+ modules.",
199
+ similes: [
200
+ "SETUP_BUSINESS",
201
+ "PHONE_ANSWERING",
202
+ "BUSINESS_AUTOMATION",
203
+ "SMS_AUTORESPONDER",
204
+ "INVOICE_CHASER",
205
+ ],
206
+ examples: [
207
+ [
208
+ {
209
+ user: "{{user1}}",
210
+ content: {
211
+ text: "I run a barbershop. Help me set up phone answering.",
212
+ },
213
+ } as ActionExample,
214
+ {
215
+ user: "{{agentName}}",
216
+ content: {
217
+ text: "Loading Business Pilot skill for your barbershop...",
218
+ action: "UNDESIRABLE_BUSINESS_PILOT",
219
+ },
220
+ } as ActionExample,
221
+ ],
222
+ ],
223
+ validate: async (_runtime: IAgentRuntime, _message: Memory) => {
224
+ return currentWorkspace !== null && "business_pilot" in (currentWorkspace?.skills || {});
225
+ },
226
+ handler: async (
227
+ runtime: IAgentRuntime,
228
+ message: Memory,
229
+ _state: State | undefined,
230
+ _options: Record<string, unknown> | undefined,
231
+ callback?: HandlerCallback
232
+ ) => {
233
+ if (!currentWorkspace) {
234
+ if (callback) callback({ text: "No soul workspace loaded." });
235
+ return false;
236
+ }
237
+
238
+ const skill = currentWorkspace.skills["business_pilot"] || "";
239
+ const context = `You are executing the Business Pilot skill.
240
+
241
+ ${skill}
242
+
243
+ The user asks: ${message.content.text}
244
+
245
+ Recommend the top 3-5 modules they should set up first with exact commands.`;
246
+
247
+ if (callback) {
248
+ callback({ text: context });
249
+ }
250
+ return true;
251
+ },
252
+ };
253
+
254
+ const memeMachineAction: Action = {
255
+ name: "UNDESIRABLE_MEME_MACHINE",
256
+ description:
257
+ "Generate memes, marketing content, content calendars, and viral social media assets using the Meme Machine skill.",
258
+ similes: [
259
+ "CREATE_MEME",
260
+ "MEME_MARKETING",
261
+ "CONTENT_CALENDAR",
262
+ "VIRAL_CONTENT",
263
+ "BRAND_VOICE",
264
+ ],
265
+ examples: [
266
+ [
267
+ {
268
+ user: "{{user1}}",
269
+ content: { text: "Create some memes for my barbershop" },
270
+ } as ActionExample,
271
+ {
272
+ user: "{{agentName}}",
273
+ content: {
274
+ text: "Firing up the Meme Machine for barbershop content...",
275
+ action: "UNDESIRABLE_MEME_MACHINE",
276
+ },
277
+ } as ActionExample,
278
+ ],
279
+ ],
280
+ validate: async (_runtime: IAgentRuntime, _message: Memory) => {
281
+ return currentWorkspace !== null && "meme_machine" in (currentWorkspace?.skills || {});
282
+ },
283
+ handler: async (
284
+ runtime: IAgentRuntime,
285
+ message: Memory,
286
+ _state: State | undefined,
287
+ _options: Record<string, unknown> | undefined,
288
+ callback?: HandlerCallback
289
+ ) => {
290
+ if (!currentWorkspace) {
291
+ if (callback) callback({ text: "No soul workspace loaded." });
292
+ return false;
293
+ }
294
+
295
+ const skill = currentWorkspace.skills["meme_machine"] || "";
296
+ const context = `You are executing the Meme Machine skill.
297
+
298
+ ${skill}
299
+
300
+ The user asks: ${message.content.text}
301
+
302
+ Create 3 meme concepts with template, text, caption, and export size.`;
303
+
304
+ if (callback) {
305
+ callback({ text: context });
306
+ }
307
+ return true;
308
+ },
309
+ };
310
+
311
+ const loadSkillAction: Action = {
312
+ name: "UNDESIRABLE_LOAD_SKILL",
313
+ description:
314
+ "Load and execute any of the 15+ skills from the Undesirable soul workspace — market analysis, content creation, portfolio check, entry signals, exit strategy, and more.",
315
+ similes: [
316
+ "USE_SKILL",
317
+ "RUN_SKILL",
318
+ "EXECUTE_SKILL",
319
+ "CHECK_PORTFOLIO",
320
+ "CONTENT_CREATION",
321
+ "ENTRY_SIGNAL",
322
+ "EXIT_STRATEGY",
323
+ ],
324
+ examples: [
325
+ [
326
+ {
327
+ user: "{{user1}}",
328
+ content: { text: "Check my portfolio" },
329
+ } as ActionExample,
330
+ {
331
+ user: "{{agentName}}",
332
+ content: {
333
+ text: "Loading portfolio check skill...",
334
+ action: "UNDESIRABLE_LOAD_SKILL",
335
+ },
336
+ } as ActionExample,
337
+ ],
338
+ ],
339
+ validate: async (_runtime: IAgentRuntime, _message: Memory) => {
340
+ return currentWorkspace !== null;
341
+ },
342
+ handler: async (
343
+ runtime: IAgentRuntime,
344
+ message: Memory,
345
+ _state: State | undefined,
346
+ _options: Record<string, unknown> | undefined,
347
+ callback?: HandlerCallback
348
+ ) => {
349
+ if (!currentWorkspace) {
350
+ if (callback) callback({ text: "No soul workspace loaded." });
351
+ return false;
352
+ }
353
+
354
+ // Try to match the best skill based on the user's message
355
+ const text = message.content.text?.toLowerCase() || "";
356
+ let matchedSkill = "";
357
+ let matchedName = "";
358
+
359
+ const skillMatches: Record<string, string[]> = {
360
+ check_portfolio: ["portfolio", "balance", "holdings", "how am i doing"],
361
+ content_creation: ["tweet", "write", "promote", "content", "thread"],
362
+ entry_signal: ["entry", "should i buy", "good time to buy", "dip"],
363
+ exit_strategy: ["exit", "sell", "take profit", "stop loss"],
364
+ conviction_score: ["conviction", "confidence", "how sure"],
365
+ rebalance_check: ["rebalance", "allocation"],
366
+ prediction_log: ["predict", "forecast", "call"],
367
+ risk_assessment: ["risk", "downside", "worst case"],
368
+ image_generation: ["image", "picture", "generate art"],
369
+ music_generation: ["music", "song", "beat", "audio"],
370
+ };
371
+
372
+ for (const [skillName, triggers] of Object.entries(skillMatches)) {
373
+ if (triggers.some((t) => text.includes(t)) && currentWorkspace.skills[skillName]) {
374
+ matchedSkill = currentWorkspace.skills[skillName];
375
+ matchedName = skillName;
376
+ break;
377
+ }
378
+ }
379
+
380
+ if (!matchedSkill) {
381
+ // Return available skills list
382
+ const available = Object.keys(currentWorkspace.skills)
383
+ .filter((k) => k !== "_index")
384
+ .join(", ");
385
+ if (callback) {
386
+ callback({
387
+ text: `Available skills: ${available}. Tell me what you need and I'll load the right one.`,
388
+ });
389
+ }
390
+ return true;
391
+ }
392
+
393
+ const context = `You are executing the ${matchedName.replace(/_/g, " ")} skill.
394
+
395
+ ${matchedSkill}
396
+
397
+ Your personality context:
398
+ ${currentWorkspace.soulMd.slice(0, 1500)}
399
+
400
+ The user asks: ${message.content.text}
401
+
402
+ Respond in character using your archetype and guardrails.`;
403
+
404
+ if (callback) {
405
+ callback({ text: context });
406
+ }
407
+ return true;
408
+ },
409
+ };
410
+
411
+ // ============================================================
412
+ // PROVIDERS
413
+ // ============================================================
414
+
415
+ const soulProvider: Provider = {
416
+ get: async (runtime: IAgentRuntime, _message: Memory) => {
417
+ // Load workspace from runtime settings if not already loaded
418
+ if (!currentWorkspace) {
419
+ const workspacePath =
420
+ (runtime.getSetting?.("UNDESIRABLES_WORKSPACE") as string) ||
421
+ process.env.UNDESIRABLES_WORKSPACE ||
422
+ "";
423
+
424
+ if (workspacePath && fs.existsSync(workspacePath)) {
425
+ currentWorkspace = loadWorkspace(workspacePath);
426
+ console.log(
427
+ `🐸 Loaded Undesirable soul: ${currentWorkspace.meta.name || "Unknown"}`
428
+ );
429
+ }
430
+ }
431
+
432
+ if (!currentWorkspace) {
433
+ return "No Undesirable soul workspace loaded. Set UNDESIRABLES_WORKSPACE env var to your downloaded workspace path.";
434
+ }
435
+
436
+ return `[SOUL CONTEXT]
437
+ Name: ${currentWorkspace.meta.name || "Unknown Undesirable"}
438
+ Archetype: ${currentWorkspace.meta.archetype || "Unknown"}
439
+ Strategy: ${currentWorkspace.meta.strategy || "Unknown"}
440
+ Token ID: ${currentWorkspace.meta.token_id || "?"}
441
+ Skills loaded: ${Object.keys(currentWorkspace.skills).filter((k) => k !== "_index").length}
442
+ Memory entries: ${currentWorkspace.memory.split("\n").filter((l) => l.trim()).length}
443
+ Predictions: ${currentWorkspace.predictions.length}
444
+
445
+ Personality: ${(currentWorkspace.meta.adjectives || []).join(", ")}
446
+
447
+ The agent should respond using the personality and style defined in its soul.
448
+ Collection: The Undesirables — 4,444 autonomous AI agents on Ethereum.
449
+ Website: https://the-undesirables.com`;
450
+ },
451
+ };
452
+
453
+ // ============================================================
454
+ // PLUGIN EXPORT
455
+ // ============================================================
456
+
457
+ const undesirablePlugin: Plugin = {
458
+ name: "plugin-undesirables",
459
+ description:
460
+ "The Undesirables — 4,444 autonomous AI agents on Ethereum. " +
461
+ "Adds soul personality, market analysis, Business Pilot (23 modules), " +
462
+ "Meme Machine, and 15+ skills to any ElizaOS agent.",
463
+ actions: [
464
+ marketAnalysisAction,
465
+ businessPilotAction,
466
+ memeMachineAction,
467
+ loadSkillAction,
468
+ ],
469
+ providers: [soulProvider],
470
+ evaluators: [],
471
+ };
472
+
473
+ export default undesirablePlugin;
474
+ export { loadWorkspace, SoulWorkspace };
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "lib": ["ES2022"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "declaration": true,
9
+ "declarationMap": true,
10
+ "sourceMap": true,
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "resolveJsonModule": true,
16
+ "moduleResolution": "node"
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }