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 +108 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +419 -0
- package/dist/index.js.map +1 -0
- package/images/banner.png +0 -0
- package/images/logo.png +0 -0
- package/package.json +36 -0
- package/src/elizaos-core.d.ts +70 -0
- package/src/index.ts +474 -0
- package/tsconfig.json +20 -0
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
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
package/images/logo.png
ADDED
|
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
|
+
}
|