@elizaos/cli 1.2.0 → 1.2.1
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/{chunk-GDP7OWFE.js → chunk-GISU7XYL.js} +2 -2
- package/dist/{chunk-IMVD3V75.js → chunk-NZGCZTGS.js} +2 -2
- package/dist/{chunk-7F7J7V7K.js → chunk-RIKSF2AY.js} +6 -6
- package/dist/{chunk-RXPGZT6Z.js → chunk-UM35ZDGG.js} +46 -46
- package/dist/commands/agent/actions/index.js +1 -1
- package/dist/commands/agent/index.js +1 -1
- package/dist/commands/create/actions/index.js +3 -3
- package/dist/commands/create/index.js +4 -4
- package/dist/index.js +5 -5
- package/dist/{registry-3LKJUU3X.js → registry-TGHIHTXG.js} +1 -1
- package/dist/{setup-JDB67JV2.js → setup-USNJOJDX.js} +2 -2
- package/dist/templates/plugin-starter/dist/index.js +12 -2
- package/dist/templates/plugin-starter/dist/index.js.map +1 -1
- package/dist/templates/plugin-starter/package.json +1 -1
- package/dist/templates/plugin-starter/src/plugin.ts +16 -4
- package/dist/templates/project-starter/package.json +4 -4
- package/dist/templates/project-starter/src/plugin.ts +29 -3
- package/dist/templates/project-tee-starter/package.json +3 -3
- package/dist/{utils-SV7PQSFH.js → utils-JZFPT3VW.js} +1 -1
- package/package.json +5 -5
- package/templates/plugin-starter/dist/index.js +12 -2
- package/templates/plugin-starter/dist/index.js.map +1 -1
- package/templates/plugin-starter/package.json +1 -1
- package/templates/plugin-starter/src/plugin.ts +16 -4
- package/templates/project-starter/package.json +4 -4
- package/templates/project-starter/src/plugin.ts +29 -3
- package/templates/project-tee-starter/package.json +3 -3
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
promptAndStoreOpenRouterKey,
|
|
14
14
|
promptAndStorePostgresUrl,
|
|
15
15
|
setupPgLite
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UM35ZDGG.js";
|
|
17
17
|
|
|
18
18
|
// src/commands/create/actions/setup.ts
|
|
19
19
|
import { existsSync } from "fs";
|
|
@@ -234,7 +234,7 @@ function resolveModelToPlugin(modelName) {
|
|
|
234
234
|
anthropic: "anthropic",
|
|
235
235
|
openrouter: "openrouter",
|
|
236
236
|
ollama: "ollama",
|
|
237
|
-
google: "google"
|
|
237
|
+
google: "google-genai"
|
|
238
238
|
};
|
|
239
239
|
return modelToPlugin[modelName] || null;
|
|
240
240
|
}
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
selectEmbeddingModel,
|
|
13
13
|
validateCreateOptions,
|
|
14
14
|
validateProjectName
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-RIKSF2AY.js";
|
|
16
16
|
import {
|
|
17
17
|
displayBanner,
|
|
18
18
|
handleError
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-UM35ZDGG.js";
|
|
20
20
|
|
|
21
21
|
// src/commands/create/index.ts
|
|
22
22
|
import { Command } from "commander";
|
|
@@ -4,7 +4,7 @@ const require = createRequire(import.meta.url);
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
setupProjectEnvironment
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GISU7XYL.js";
|
|
8
8
|
import {
|
|
9
9
|
buildProjectWithSpinner,
|
|
10
10
|
copyTemplate,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getDisplayDirectory,
|
|
13
13
|
installDependenciesWithSpinner,
|
|
14
14
|
runTasks
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-UM35ZDGG.js";
|
|
16
16
|
|
|
17
17
|
// src/characters/eliza.ts
|
|
18
18
|
var baseCharacter = {
|
|
@@ -605,8 +605,8 @@ async function createTEEProject(projectName, targetDir, database, aiModel, embed
|
|
|
605
605
|
await withCleanupOnInterrupt(teeTargetDir, projectName, async () => {
|
|
606
606
|
await fs2.mkdir(teeTargetDir, { recursive: true });
|
|
607
607
|
if (!isNonInteractive) {
|
|
608
|
-
const { setupAIModelConfig, setupEmbeddingModelConfig } = await import("./setup-
|
|
609
|
-
const { promptAndStorePostgresUrl } = await import("./utils-
|
|
608
|
+
const { setupAIModelConfig, setupEmbeddingModelConfig } = await import("./setup-USNJOJDX.js");
|
|
609
|
+
const { promptAndStorePostgresUrl } = await import("./utils-JZFPT3VW.js");
|
|
610
610
|
const envFilePath = `${teeTargetDir}/.env`;
|
|
611
611
|
if (database === "postgres") {
|
|
612
612
|
await promptAndStorePostgresUrl(envFilePath);
|
|
@@ -666,8 +666,8 @@ async function createProject(projectName, targetDir, database, aiModel, embeddin
|
|
|
666
666
|
await fs2.mkdir(projectTargetDir, { recursive: true });
|
|
667
667
|
}
|
|
668
668
|
if (!isNonInteractive) {
|
|
669
|
-
const { setupAIModelConfig, setupEmbeddingModelConfig } = await import("./setup-
|
|
670
|
-
const { promptAndStorePostgresUrl } = await import("./utils-
|
|
669
|
+
const { setupAIModelConfig, setupEmbeddingModelConfig } = await import("./setup-USNJOJDX.js");
|
|
670
|
+
const { promptAndStorePostgresUrl } = await import("./utils-JZFPT3VW.js");
|
|
671
671
|
const envFilePath = `${projectTargetDir}/.env`;
|
|
672
672
|
if (database === "postgres") {
|
|
673
673
|
await promptAndStorePostgresUrl(envFilePath);
|
|
@@ -30,7 +30,7 @@ import fs from "fs/promises";
|
|
|
30
30
|
import path2 from "path";
|
|
31
31
|
import * as semver from "semver";
|
|
32
32
|
import { fileURLToPath } from "url";
|
|
33
|
-
import { logger as
|
|
33
|
+
import { logger as logger2 } from "@elizaos/core";
|
|
34
34
|
import { existsSync as existsSync2, statSync, readFileSync } from "fs";
|
|
35
35
|
import { execSync } from "child_process";
|
|
36
36
|
|
|
@@ -87,7 +87,7 @@ async function resolvePgliteDir(dir, fallbackDir, targetProjectDir) {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// src/utils/auto-install-bun.ts
|
|
90
|
-
import { logger
|
|
90
|
+
import { logger } from "@elizaos/core";
|
|
91
91
|
import { execa } from "execa";
|
|
92
92
|
async function autoInstallBun() {
|
|
93
93
|
const platform = process.platform;
|
|
@@ -96,15 +96,15 @@ async function autoInstallBun() {
|
|
|
96
96
|
return true;
|
|
97
97
|
} catch {
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
logger.info(`${emoji.rocket("Bun is required for ElizaOS CLI. Installing automatically...")}`);
|
|
100
100
|
try {
|
|
101
101
|
if (platform === "win32") {
|
|
102
|
-
|
|
102
|
+
logger.info("Installing Bun on Windows...");
|
|
103
103
|
await execa("powershell", ["-c", "irm bun.sh/install.ps1 | iex"], {
|
|
104
104
|
stdio: "inherit"
|
|
105
105
|
});
|
|
106
106
|
} else {
|
|
107
|
-
|
|
107
|
+
logger.info("Installing Bun on Linux/macOS...");
|
|
108
108
|
await execa("sh", ["-c", "curl -fsSL https://bun.sh/install | bash"], {
|
|
109
109
|
stdio: "inherit"
|
|
110
110
|
});
|
|
@@ -114,24 +114,24 @@ async function autoInstallBun() {
|
|
|
114
114
|
process.env.PATH = `${bunPath}${platform === "win32" ? ";" : ":"}${process.env.PATH}`;
|
|
115
115
|
}
|
|
116
116
|
await execa("bun", ["--version"], { stdio: "ignore" });
|
|
117
|
-
|
|
117
|
+
logger.success(`${emoji.success("Bun installed successfully!")}`);
|
|
118
118
|
return true;
|
|
119
119
|
} catch (error) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
logger.error(`${emoji.error("Failed to automatically install Bun:")}`);
|
|
121
|
+
logger.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
122
|
+
logger.info(`
|
|
123
123
|
${emoji.info("Please install Bun manually:")}`);
|
|
124
124
|
if (platform === "win32") {
|
|
125
|
-
|
|
125
|
+
logger.info(' Windows: powershell -c "irm bun.sh/install.ps1 | iex"');
|
|
126
126
|
} else {
|
|
127
|
-
|
|
127
|
+
logger.info(" Linux/macOS: curl -fsSL https://bun.sh/install | bash");
|
|
128
128
|
if (platform === "darwin") {
|
|
129
|
-
|
|
129
|
+
logger.info(" macOS (Homebrew): brew install bun");
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
|
|
132
|
+
logger.info(`
|
|
133
133
|
${emoji.link("More options: https://bun.sh/docs/installation")}`);
|
|
134
|
-
|
|
134
|
+
logger.info(
|
|
135
135
|
`
|
|
136
136
|
${emoji.tip("After installation, restart your terminal or source your shell profile")}`
|
|
137
137
|
);
|
|
@@ -164,7 +164,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
164
164
|
* Gets operating system information
|
|
165
165
|
*/
|
|
166
166
|
async getOSInfo() {
|
|
167
|
-
|
|
167
|
+
logger2.debug("[UserEnvironment] Detecting OS information");
|
|
168
168
|
return {
|
|
169
169
|
platform: os.platform(),
|
|
170
170
|
release: os.release(),
|
|
@@ -178,7 +178,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
178
178
|
* Gets CLI version and package information
|
|
179
179
|
*/
|
|
180
180
|
async getCLIInfo() {
|
|
181
|
-
|
|
181
|
+
logger2.debug("[UserEnvironment] Getting CLI information");
|
|
182
182
|
try {
|
|
183
183
|
const __filename2 = fileURLToPath(import.meta.url);
|
|
184
184
|
const __dirname2 = path2.dirname(__filename2);
|
|
@@ -194,7 +194,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
194
194
|
path: process.argv[1] || ""
|
|
195
195
|
};
|
|
196
196
|
} catch (error) {
|
|
197
|
-
|
|
197
|
+
logger2.warn(
|
|
198
198
|
`[UserEnvironment] Error getting CLI info: ${error instanceof Error ? error.message : String(error)}`
|
|
199
199
|
);
|
|
200
200
|
return {
|
|
@@ -208,20 +208,20 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
208
208
|
* Detects the active package manager - always returns bun for ElizaOS CLI
|
|
209
209
|
*/
|
|
210
210
|
async getPackageManagerInfo() {
|
|
211
|
-
|
|
211
|
+
logger2.debug("[UserEnvironment] Using bun as the package manager for ElizaOS CLI");
|
|
212
212
|
const isNpx = process.env.npm_execpath?.includes("npx");
|
|
213
213
|
const isBunx = process.argv[0]?.includes("bun");
|
|
214
214
|
let version = null;
|
|
215
215
|
try {
|
|
216
216
|
const { stdout } = await import("execa").then(({ execa: execa10 }) => execa10("bun", ["--version"]));
|
|
217
217
|
version = stdout.trim();
|
|
218
|
-
|
|
218
|
+
logger2.debug(`[UserEnvironment] Bun version: ${version}`);
|
|
219
219
|
} catch (e) {
|
|
220
|
-
|
|
220
|
+
logger2.debug(
|
|
221
221
|
`[UserEnvironment] Could not get bun version: ${e instanceof Error ? e.message : String(e)}`
|
|
222
222
|
);
|
|
223
223
|
if (shouldAutoInstall()) {
|
|
224
|
-
|
|
224
|
+
logger2.info(`${emoji.info("Attempting to automatically install Bun...")}`);
|
|
225
225
|
const installSuccess = await autoInstallBun();
|
|
226
226
|
if (installSuccess) {
|
|
227
227
|
try {
|
|
@@ -229,9 +229,9 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
229
229
|
({ execa: execa10 }) => execa10("bun", ["--version"])
|
|
230
230
|
);
|
|
231
231
|
version = stdout.trim();
|
|
232
|
-
|
|
232
|
+
logger2.debug(`[UserEnvironment] Bun version after auto-install: ${version}`);
|
|
233
233
|
} catch (retryError) {
|
|
234
|
-
|
|
234
|
+
logger2.error(
|
|
235
235
|
`Failed to verify Bun installation after auto-install: ${retryError instanceof Error ? retryError.message : String(retryError)}`
|
|
236
236
|
);
|
|
237
237
|
}
|
|
@@ -239,27 +239,27 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
239
239
|
}
|
|
240
240
|
if (!version) {
|
|
241
241
|
const platform = process.platform;
|
|
242
|
-
|
|
242
|
+
logger2.error(
|
|
243
243
|
`${emoji.error("Bun is required for ElizaOS CLI but is not installed or not found in PATH.")}`
|
|
244
244
|
);
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
logger2.error("");
|
|
246
|
+
logger2.error(
|
|
247
247
|
`${emoji.rocket("Install Bun using the appropriate command for your system:")}`
|
|
248
248
|
);
|
|
249
|
-
|
|
249
|
+
logger2.error("");
|
|
250
250
|
if (platform === "win32") {
|
|
251
|
-
|
|
251
|
+
logger2.error(' Windows: powershell -c "irm bun.sh/install.ps1 | iex"');
|
|
252
252
|
} else {
|
|
253
|
-
|
|
253
|
+
logger2.error(" Linux/macOS: curl -fsSL https://bun.sh/install | bash");
|
|
254
254
|
if (platform === "darwin") {
|
|
255
|
-
|
|
255
|
+
logger2.error(" macOS (Homebrew): brew install bun");
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
258
|
+
logger2.error("");
|
|
259
|
+
logger2.error(" More options: https://bun.sh/docs/installation");
|
|
260
|
+
logger2.error(" After installation, restart your terminal or source your shell profile");
|
|
261
|
+
logger2.error("");
|
|
262
|
+
logger2.error("\u{1F534} Exiting: Bun installation is required to continue.");
|
|
263
263
|
process.exit(1);
|
|
264
264
|
}
|
|
265
265
|
}
|
|
@@ -326,7 +326,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
326
326
|
const projectRootForPaths = monorepoRoot || process.cwd();
|
|
327
327
|
const elizaDir = path2.join(projectRootForPaths, ".eliza");
|
|
328
328
|
const envFilePath = resolveEnvFile(process.cwd(), monorepoRoot ?? void 0);
|
|
329
|
-
|
|
329
|
+
logger2.debug("[UserEnvironment] Detected monorepo root:", monorepoRoot || "Not in monorepo");
|
|
330
330
|
return {
|
|
331
331
|
elizaDir,
|
|
332
332
|
envFilePath,
|
|
@@ -344,7 +344,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
344
344
|
if (this.cachedInfo[cacheKey]) {
|
|
345
345
|
return this.cachedInfo[cacheKey];
|
|
346
346
|
}
|
|
347
|
-
|
|
347
|
+
logger2.debug(`[UserEnvironment] Gathering environment information for directory: ${cacheKey}`);
|
|
348
348
|
const [os2, cli, packageManager, paths, env] = await Promise.all([
|
|
349
349
|
this.getOSInfo(),
|
|
350
350
|
this.getCLIInfo(),
|
|
@@ -398,7 +398,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
398
398
|
if (minVer) {
|
|
399
399
|
return minVer.version;
|
|
400
400
|
} else {
|
|
401
|
-
|
|
401
|
+
logger2.warn(
|
|
402
402
|
`Could not parse semver range '${versionRange}' for package ${packageName}. Falling back to original string.`
|
|
403
403
|
);
|
|
404
404
|
return versionRange;
|
|
@@ -409,15 +409,15 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
409
409
|
const { execa: execa10 } = await import("execa");
|
|
410
410
|
const { stdout } = await execa10("npm", ["view", packageName, "version"]);
|
|
411
411
|
if (stdout?.trim()) {
|
|
412
|
-
|
|
412
|
+
logger2.info(`Found latest version of ${packageName} from npm: ${stdout.trim()}`);
|
|
413
413
|
return stdout.trim();
|
|
414
414
|
}
|
|
415
415
|
} catch (npmError) {
|
|
416
|
-
|
|
416
|
+
logger2.warn(`Could not get latest version from npm: ${npmError}`);
|
|
417
417
|
}
|
|
418
418
|
return "0.25.9";
|
|
419
419
|
} catch (error) {
|
|
420
|
-
|
|
420
|
+
logger2.warn(`Error getting package version for ${packageName}: ${error}`);
|
|
421
421
|
return "0.25.9";
|
|
422
422
|
}
|
|
423
423
|
}
|
|
@@ -434,7 +434,7 @@ var UserEnvironment = class _UserEnvironment {
|
|
|
434
434
|
const pluginPackages = packagesDirEntries.filter((entry) => entry.isDirectory() && entry.name.startsWith("plugin-")).map((entry) => `@elizaos/${entry.name}`);
|
|
435
435
|
return pluginPackages;
|
|
436
436
|
} catch (error) {
|
|
437
|
-
|
|
437
|
+
logger2.warn(`Error getting local packages: ${error}`);
|
|
438
438
|
return [];
|
|
439
439
|
}
|
|
440
440
|
}
|
|
@@ -616,7 +616,7 @@ function isValidForUpdates(info) {
|
|
|
616
616
|
import { execa as execa2 } from "execa";
|
|
617
617
|
import * as clack from "@clack/prompts";
|
|
618
618
|
import colors from "yoctocolors";
|
|
619
|
-
import { parseBooleanFromText } from "@elizaos/core";
|
|
619
|
+
import { parseBooleanFromText, logger as logger3 } from "@elizaos/core";
|
|
620
620
|
function isQuietMode() {
|
|
621
621
|
return parseBooleanFromText(process.env.QUIET_MODE);
|
|
622
622
|
}
|
|
@@ -719,7 +719,7 @@ async function installPluginWithSpinner(pluginName, targetDir, purpose = "") {
|
|
|
719
719
|
spinner3.stop(colors.green(`\u2713 ${packageName} installed successfully`));
|
|
720
720
|
} else {
|
|
721
721
|
spinner3.stop(colors.yellow(`\u26A0 Failed to install ${packageName} (optional)`));
|
|
722
|
-
|
|
722
|
+
logger3.debug(`Plugin installation failed: ${packageName}`, {
|
|
723
723
|
exitCode: result.exitCode,
|
|
724
724
|
stderr: result.stderr,
|
|
725
725
|
stdout: result.stdout
|
|
@@ -727,7 +727,7 @@ async function installPluginWithSpinner(pluginName, targetDir, purpose = "") {
|
|
|
727
727
|
}
|
|
728
728
|
} catch (error) {
|
|
729
729
|
spinner3.stop(colors.yellow(`\u26A0 Failed to install ${packageName} (optional)`));
|
|
730
|
-
|
|
730
|
+
logger3.debug(`Plugin installation error: ${packageName}`, error);
|
|
731
731
|
}
|
|
732
732
|
}
|
|
733
733
|
function createTask(title, fn) {
|
|
@@ -2757,7 +2757,7 @@ async function getGitHubCredentials() {
|
|
|
2757
2757
|
}
|
|
2758
2758
|
logger10.warn("Invalid GitHub token found in environment variables");
|
|
2759
2759
|
}
|
|
2760
|
-
const { getGitHubToken: getGitHubToken2 } = await import("./registry-
|
|
2760
|
+
const { getGitHubToken: getGitHubToken2 } = await import("./registry-TGHIHTXG.js");
|
|
2761
2761
|
const token = await getGitHubToken2() || void 0;
|
|
2762
2762
|
if (token) {
|
|
2763
2763
|
const isValid2 = await validateGitHubToken(token);
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
createPlugin,
|
|
8
8
|
createProject,
|
|
9
9
|
createTEEProject
|
|
10
|
-
} from "../../../chunk-
|
|
10
|
+
} from "../../../chunk-RIKSF2AY.js";
|
|
11
11
|
import {
|
|
12
12
|
createProjectDirectories,
|
|
13
13
|
setupAIModelConfig,
|
|
14
14
|
setupEmbeddingModelConfig,
|
|
15
15
|
setupProjectEnvironment
|
|
16
|
-
} from "../../../chunk-
|
|
17
|
-
import "../../../chunk-
|
|
16
|
+
} from "../../../chunk-GISU7XYL.js";
|
|
17
|
+
import "../../../chunk-UM35ZDGG.js";
|
|
18
18
|
import "../../../chunk-7PPBVSWE.js";
|
|
19
19
|
import "../../../chunk-F24MS2YR.js";
|
|
20
20
|
import "../../../chunk-AQ6OMR2A.js";
|
|
@@ -4,10 +4,10 @@ const require = createRequire(import.meta.url);
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
create
|
|
7
|
-
} from "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
9
|
-
import "../../chunk-
|
|
10
|
-
import "../../chunk-
|
|
7
|
+
} from "../../chunk-NZGCZTGS.js";
|
|
8
|
+
import "../../chunk-RIKSF2AY.js";
|
|
9
|
+
import "../../chunk-GISU7XYL.js";
|
|
10
|
+
import "../../chunk-UM35ZDGG.js";
|
|
11
11
|
import "../../chunk-7PPBVSWE.js";
|
|
12
12
|
import "../../chunk-F24MS2YR.js";
|
|
13
13
|
import "../../chunk-AQ6OMR2A.js";
|
package/dist/index.js
CHANGED
|
@@ -5,11 +5,11 @@ const require = createRequire(import.meta.url);
|
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
create
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-NZGCZTGS.js";
|
|
9
9
|
import {
|
|
10
10
|
getElizaCharacter
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-RIKSF2AY.js";
|
|
12
|
+
import "./chunk-GISU7XYL.js";
|
|
13
13
|
import {
|
|
14
14
|
TestRunner,
|
|
15
15
|
UserEnvironment,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
testPublishToGitHub,
|
|
47
47
|
testPublishToNpm,
|
|
48
48
|
validateDataDir
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-UM35ZDGG.js";
|
|
50
50
|
import {
|
|
51
51
|
configureEmojis,
|
|
52
52
|
emoji,
|
|
@@ -4812,7 +4812,7 @@ async function installPluginDependencies(projectInfo) {
|
|
|
4812
4812
|
};
|
|
4813
4813
|
await fs11.promises.writeFile(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
|
|
4814
4814
|
}
|
|
4815
|
-
const { installPlugin: installPlugin2 } = await import("./utils-
|
|
4815
|
+
const { installPlugin: installPlugin2 } = await import("./utils-JZFPT3VW.js");
|
|
4816
4816
|
for (const dependency of project.pluginModule.dependencies) {
|
|
4817
4817
|
await installPlugin2(dependency, pluginsDir);
|
|
4818
4818
|
const dependencyPath = path24.join(pluginsDir, "node_modules", dependency);
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
setupAIModelConfig,
|
|
8
8
|
setupEmbeddingModelConfig,
|
|
9
9
|
setupProjectEnvironment
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-GISU7XYL.js";
|
|
11
|
+
import "./chunk-UM35ZDGG.js";
|
|
12
12
|
import "./chunk-7PPBVSWE.js";
|
|
13
13
|
import "./chunk-F24MS2YR.js";
|
|
14
14
|
import "./chunk-AQ6OMR2A.js";
|
|
@@ -216,10 +216,20 @@ var helloWorldAction = {
|
|
|
216
216
|
if (callback) {
|
|
217
217
|
await callback(responseContent);
|
|
218
218
|
}
|
|
219
|
-
return
|
|
219
|
+
return {
|
|
220
|
+
text: "hello world!",
|
|
221
|
+
success: true,
|
|
222
|
+
data: {
|
|
223
|
+
actions: ["HELLO_WORLD"],
|
|
224
|
+
source: message.content.source
|
|
225
|
+
}
|
|
226
|
+
};
|
|
220
227
|
} catch (error) {
|
|
221
228
|
logger.error("Error in HELLO_WORLD action:", error);
|
|
222
|
-
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
232
|
+
};
|
|
223
233
|
}
|
|
224
234
|
},
|
|
225
235
|
examples: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts","../src/__tests__/e2e/starter-plugin.ts","../src/index.ts"],"sourcesContent":["import type { Plugin } from '@elizaos/core';\nimport {\n type Action,\n type Content,\n type GenerateTextParams,\n type HandlerCallback,\n type IAgentRuntime,\n type Memory,\n ModelType,\n type Provider,\n type ProviderResult,\n Service,\n type State,\n logger,\n} from '@elizaos/core';\nimport { z } from 'zod';\nimport { StarterPluginTestSuite } from './tests';\n\n/**\n * Defines the configuration schema for a plugin, including the validation rules for the plugin name.\n *\n * @type {import('zod').ZodObject<{ EXAMPLE_PLUGIN_VARIABLE: import('zod').ZodString }>}\n */\nconst configSchema = z.object({\n EXAMPLE_PLUGIN_VARIABLE: z\n .string()\n .min(1, 'Example plugin variable is not provided')\n .optional()\n .transform((val) => {\n if (!val) {\n logger.warn('Example plugin variable is not provided (this is expected)');\n }\n return val;\n }),\n});\n\n/**\n * Example HelloWorld action\n * This demonstrates the simplest possible action structure\n */\n/**\n * Action representing a hello world message.\n * @typedef {Object} Action\n * @property {string} name - The name of the action.\n * @property {string[]} similes - An array of related actions.\n * @property {string} description - A brief description of the action.\n * @property {Function} validate - Asynchronous function to validate the action.\n * @property {Function} handler - Asynchronous function to handle the action and generate a response.\n * @property {Object[]} examples - An array of example inputs and expected outputs for the action.\n */\nconst helloWorldAction: Action = {\n name: 'HELLO_WORLD',\n similes: ['GREET', 'SAY_HELLO'],\n description: 'Responds with a simple hello world message',\n\n validate: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<boolean> => {\n // Always valid\n return true;\n },\n\n handler: async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n _options: any,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ) => {\n try {\n logger.info('Handling HELLO_WORLD action');\n\n // Simple response content\n const responseContent: Content = {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n source: message.content.source,\n };\n\n // Call back with the hello world message if callback is provided\n if (callback) {\n await callback(responseContent);\n }\n\n return responseContent;\n } catch (error) {\n logger.error('Error in HELLO_WORLD action:', error);\n throw error;\n }\n },\n\n examples: [\n [\n {\n name: '{{name1}}',\n content: {\n text: 'Can you say hello?',\n },\n },\n {\n name: '{{name2}}',\n content: {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n },\n },\n ],\n ],\n};\n\n/**\n * Example Hello World Provider\n * This demonstrates the simplest possible provider implementation\n */\nconst helloWorldProvider: Provider = {\n name: 'HELLO_WORLD_PROVIDER',\n description: 'A simple example provider',\n\n get: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<ProviderResult> => {\n return {\n text: 'I am a provider',\n values: {},\n data: {},\n };\n },\n};\n\nexport class StarterService extends Service {\n static serviceType = 'starter';\n capabilityDescription =\n 'This is a starter service which is attached to the agent through the starter plugin.';\n constructor(protected runtime: IAgentRuntime) {\n super(runtime);\n }\n\n static async start(runtime: IAgentRuntime) {\n logger.info(`*** Starting starter service - MODIFIED: ${new Date().toISOString()} ***`);\n const service = new StarterService(runtime);\n return service;\n }\n\n static async stop(runtime: IAgentRuntime) {\n logger.info('*** TESTING DEV MODE - STOP MESSAGE CHANGED! ***');\n // get the service from the runtime\n const service = runtime.getService(StarterService.serviceType);\n if (!service) {\n throw new Error('Starter service not found');\n }\n service.stop();\n }\n\n async stop() {\n logger.info('*** THIRD CHANGE - TESTING FILE WATCHING! ***');\n }\n}\n\nexport const starterPlugin: Plugin = {\n name: 'plugin-starter',\n description: 'Plugin starter for elizaOS',\n config: {\n EXAMPLE_PLUGIN_VARIABLE: process.env.EXAMPLE_PLUGIN_VARIABLE,\n },\n async init(config: Record<string, string>) {\n logger.info('*** TESTING DEV MODE - PLUGIN MODIFIED AND RELOADED! ***');\n try {\n const validatedConfig = await configSchema.parseAsync(config);\n\n // Set all environment variables at once\n for (const [key, value] of Object.entries(validatedConfig)) {\n if (value) process.env[key] = value;\n }\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Invalid plugin configuration: ${error.errors.map((e) => e.message).join(', ')}`\n );\n }\n throw error;\n }\n },\n models: {\n [ModelType.TEXT_SMALL]: async (\n _runtime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n return 'Never gonna give you up, never gonna let you down, never gonna run around and desert you...';\n },\n [ModelType.TEXT_LARGE]: async (\n _runtime,\n {\n prompt,\n stopSequences = [],\n maxTokens = 8192,\n temperature = 0.7,\n frequencyPenalty = 0.7,\n presencePenalty = 0.7,\n }: GenerateTextParams\n ) => {\n return 'Never gonna make you cry, never gonna say goodbye, never gonna tell a lie and hurt you...';\n },\n },\n routes: [\n {\n name: 'hello-world-route',\n path: '/helloworld',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // send a response\n res.json({\n message: 'Hello World!',\n });\n },\n },\n {\n name: 'current-time-route',\n path: '/api/time',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // Return current time in various formats\n const now = new Date();\n res.json({\n timestamp: now.toISOString(),\n unix: Math.floor(now.getTime() / 1000),\n formatted: now.toLocaleString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n },\n },\n ],\n events: {\n MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n VOICE_MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('VOICE_MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_CONNECTED: [\n async (params) => {\n logger.debug('WORLD_CONNECTED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_JOINED: [\n async (params) => {\n logger.debug('WORLD_JOINED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n },\n services: [StarterService],\n actions: [helloWorldAction],\n providers: [helloWorldProvider],\n tests: [StarterPluginTestSuite],\n // dependencies: ['@elizaos/plugin-knowledge'], <--- plugin dependecies go here (if requires another plugin)\n};\n\nexport default starterPlugin;\n","import { type Content, type HandlerCallback } from '@elizaos/core';\n\n/**\n * E2E (End-to-End) Test Suite for ElizaOS Plugins\n * ================================================\n *\n * This file contains end-to-end tests that run within a real ElizaOS runtime environment.\n * Unlike unit tests that test individual components in isolation, e2e tests validate\n * the entire plugin behavior in a production-like environment.\n *\n * NOTE: The tests are properly structured and included in the plugin build.\n * If the test runner is not detecting these tests, it may be looking at the wrong\n * plugin name or there may be a test runner configuration issue. The tests are\n * exported correctly through src/tests.ts and included in the plugin's tests array.\n *\n * HOW E2E TESTS WORK:\n * -------------------\n * 1. Tests are executed by the ElizaOS test runner using `elizaos test e2e`\n * 2. Each test receives a real runtime instance with the plugin loaded\n * 3. Tests can interact with the runtime just like in production\n * 4. Tests throw errors to indicate failure (no assertion library needed)\n *\n * WRITING NEW E2E TESTS:\n * ----------------------\n * 1. Add a new test object to the `tests` array below\n * 2. Each test must have:\n * - `name`: A unique identifier for the test\n * - `fn`: An async function that receives the runtime and performs the test\n *\n * Example structure:\n * ```typescript\n * {\n * name: 'my_new_test',\n * fn: async (runtime) => {\n * // Your test logic here\n * if (someCondition !== expected) {\n * throw new Error('Test failed: reason');\n * }\n * }\n * }\n * ```\n *\n * BEST PRACTICES:\n * ---------------\n * - Test real user scenarios, not implementation details\n * - Use descriptive test names that explain what's being tested\n * - Include clear error messages that help diagnose failures\n * - Test both success and failure paths\n * - Clean up any resources created during tests\n *\n * AVAILABLE RUNTIME METHODS:\n * --------------------------\n * - runtime.getService(type): Get a service instance\n * - runtime.character: Access character configuration\n * - runtime.models: Access AI models\n * - runtime.db: Access database methods\n * - runtime.actions: Access registered actions\n * - runtime.providers: Access registered providers\n *\n * For more details, see the ElizaOS documentation.\n */\n\n// Define a minimal TestSuite interface that matches what's needed\ninterface TestSuite {\n name: string;\n description?: string;\n tests: Array<{\n name: string;\n fn: (runtime: any) => Promise<any>;\n }>;\n}\n\n// Define minimal interfaces for the types we need\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\ninterface Memory {\n entityId: UUID;\n roomId: UUID;\n content: {\n text: string;\n source: string;\n actions?: string[];\n };\n}\n\ninterface State {\n values: Record<string, any>;\n data: Record<string, any>;\n text: string;\n}\n\nexport const StarterPluginTestSuite: TestSuite = {\n name: 'plugin_starter_test_suite',\n description: 'E2E tests for the starter plugin',\n\n tests: [\n /**\n * Basic Plugin Verification Test\n * ------------------------------\n * This test verifies that the plugin is properly loaded and initialized\n * within the runtime environment.\n */\n {\n name: 'example_test',\n fn: async (runtime) => {\n // Test the character name\n if (runtime.character.name !== 'Eliza') {\n throw new Error(\n `Expected character name to be \"Eliza\" but got \"${runtime.character.name}\"`\n );\n }\n // Verify the plugin is loaded properly\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n },\n },\n\n /**\n * Action Registration Test\n * ------------------------\n * Verifies that custom actions are properly registered with the runtime.\n * This is important to ensure actions are available for the agent to use.\n */\n {\n name: 'should_have_hello_world_action',\n fn: async (runtime) => {\n // Access actions through runtime.actions instead of getPlugin\n const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');\n if (!actionExists) {\n throw new Error('Hello world action not found in runtime actions');\n }\n },\n },\n\n /**\n * Hello World Action Response Test\n * ---------------------------------\n * This test demonstrates a complete scenario where:\n * 1. The agent is asked to say \"hello\"\n * 2. The HELLO_WORLD action is triggered\n * 3. The agent responds with text containing \"hello world\"\n *\n * This is a key pattern for testing agent behaviors - you simulate\n * a user message and verify the agent's response.\n */\n {\n name: 'hello_world_action_test',\n fn: async (runtime) => {\n // Create a test message asking the agent to say hello\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'Can you say hello?',\n source: 'test',\n actions: ['HELLO_WORLD'], // Specify which action we expect to trigger\n },\n };\n\n // Create a test state (can include context if needed)\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n let responseText = '';\n let responseReceived = false;\n\n // Find the hello world action in runtime.actions\n const helloWorldAction = runtime.actions?.find((a) => a.name === 'HELLO_WORLD');\n if (!helloWorldAction) {\n throw new Error('Hello world action not found in runtime actions');\n }\n\n // Create a callback that captures the agent's response\n // This simulates how the runtime would handle the action's response\n const callback: HandlerCallback = async (response: Content) => {\n responseReceived = true;\n responseText = response.text || '';\n\n // Verify the response includes the expected action\n if (!response.actions?.includes('HELLO_WORLD')) {\n throw new Error('Response did not include HELLO_WORLD action');\n }\n\n // Return Promise<Memory[]> as required by the HandlerCallback interface\n return Promise.resolve([]);\n };\n\n // Execute the action - this simulates the runtime calling the action\n await helloWorldAction.handler(runtime, testMessage, testState, {}, callback);\n\n // Verify we received a response\n if (!responseReceived) {\n throw new Error('Hello world action did not produce a response');\n }\n\n // Verify the response contains \"hello world\" (case-insensitive)\n if (!responseText.toLowerCase().includes('hello world')) {\n throw new Error(`Expected response to contain \"hello world\" but got: \"${responseText}\"`);\n }\n\n // Success! The agent responded with \"hello world\" as expected\n },\n },\n\n /**\n * Provider Functionality Test\n * ---------------------------\n * Tests that providers can supply data to the agent when needed.\n * Providers are used to fetch external data or compute values.\n */\n {\n name: 'hello_world_provider_test',\n fn: async (runtime) => {\n // Create a test message\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'What can you provide?',\n source: 'test',\n },\n };\n\n // Create a test state\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n // Find the hello world provider in runtime.providers\n const helloWorldProvider = runtime.providers?.find(\n (p) => p.name === 'HELLO_WORLD_PROVIDER'\n );\n if (!helloWorldProvider) {\n throw new Error('Hello world provider not found in runtime providers');\n }\n\n // Test the provider\n const result = await helloWorldProvider.get(runtime, testMessage, testState);\n\n if (result.text !== 'I am a provider') {\n throw new Error(`Expected provider to return \"I am a provider\", got \"${result.text}\"`);\n }\n },\n },\n\n /**\n * Service Lifecycle Test\n * ----------------------\n * Verifies that services can be started, accessed, and stopped properly.\n * Services run background tasks or manage long-lived resources.\n */\n {\n name: 'starter_service_test',\n fn: async (runtime) => {\n // Get the service from the runtime\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n\n // Check service capability description\n if (\n service.capabilityDescription !==\n 'This is a starter service which is attached to the agent through the starter plugin.'\n ) {\n throw new Error('Incorrect service capability description');\n }\n\n // Test service stop method\n await service.stop();\n },\n },\n\n /**\n * ADD YOUR CUSTOM TESTS HERE\n * --------------------------\n * To add a new test:\n *\n * 1. Copy this template:\n * ```typescript\n * {\n * name: 'your_test_name',\n * fn: async (runtime) => {\n * // Setup: Create any test data needed\n *\n * // Action: Perform the operation you want to test\n *\n * // Assert: Check the results\n * if (result !== expected) {\n * throw new Error(`Expected ${expected} but got ${result}`);\n * }\n * }\n * }\n * ```\n *\n * 2. Common test patterns:\n * - Test action responses to specific prompts\n * - Verify provider data under different conditions\n * - Check service behavior during lifecycle events\n * - Validate plugin configuration handling\n * - Test error cases and edge conditions\n *\n * 3. Tips:\n * - Use meaningful variable names\n * - Include helpful error messages\n * - Test one thing per test\n * - Consider both success and failure scenarios\n */\n ],\n};\n\n// Export a default instance of the test suite for the E2E test runner\nexport default StarterPluginTestSuite;\n","import { starterPlugin } from './plugin.ts';\n\nexport { starterPlugin, StarterService } from './plugin.ts';\nexport default starterPlugin;\n"],"mappings":"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","names":["helloWorldAction","helloWorldProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/__tests__/e2e/starter-plugin.ts","../src/index.ts"],"sourcesContent":["import type { Plugin } from '@elizaos/core';\nimport {\n type Action,\n type ActionResult,\n type Content,\n type GenerateTextParams,\n type HandlerCallback,\n type IAgentRuntime,\n type Memory,\n ModelType,\n type Provider,\n type ProviderResult,\n Service,\n type State,\n logger,\n} from '@elizaos/core';\nimport { z } from 'zod';\nimport { StarterPluginTestSuite } from './tests';\n\n/**\n * Defines the configuration schema for a plugin, including the validation rules for the plugin name.\n *\n * @type {import('zod').ZodObject<{ EXAMPLE_PLUGIN_VARIABLE: import('zod').ZodString }>}\n */\nconst configSchema = z.object({\n EXAMPLE_PLUGIN_VARIABLE: z\n .string()\n .min(1, 'Example plugin variable is not provided')\n .optional()\n .transform((val) => {\n if (!val) {\n logger.warn('Example plugin variable is not provided (this is expected)');\n }\n return val;\n }),\n});\n\n/**\n * Example HelloWorld action\n * This demonstrates the simplest possible action structure\n */\n/**\n * Action representing a hello world message.\n * @typedef {Object} Action\n * @property {string} name - The name of the action.\n * @property {string[]} similes - An array of related actions.\n * @property {string} description - A brief description of the action.\n * @property {Function} validate - Asynchronous function to validate the action.\n * @property {Function} handler - Asynchronous function to handle the action and generate a response.\n * @property {Object[]} examples - An array of example inputs and expected outputs for the action.\n */\nconst helloWorldAction: Action = {\n name: 'HELLO_WORLD',\n similes: ['GREET', 'SAY_HELLO'],\n description: 'Responds with a simple hello world message',\n\n validate: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<boolean> => {\n // Always valid\n return true;\n },\n\n handler: async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n _options: any,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ): Promise<ActionResult> => {\n try {\n logger.info('Handling HELLO_WORLD action');\n\n // Simple response content for callback\n const responseContent: Content = {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n source: message.content.source,\n };\n\n // Call back with the hello world message if callback is provided\n if (callback) {\n await callback(responseContent);\n }\n\n // Return ActionResult\n return {\n text: 'hello world!',\n success: true,\n data: {\n actions: ['HELLO_WORLD'],\n source: message.content.source,\n },\n };\n } catch (error) {\n logger.error('Error in HELLO_WORLD action:', error);\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n },\n\n examples: [\n [\n {\n name: '{{name1}}',\n content: {\n text: 'Can you say hello?',\n },\n },\n {\n name: '{{name2}}',\n content: {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n },\n },\n ],\n ],\n};\n\n/**\n * Example Hello World Provider\n * This demonstrates the simplest possible provider implementation\n */\nconst helloWorldProvider: Provider = {\n name: 'HELLO_WORLD_PROVIDER',\n description: 'A simple example provider',\n\n get: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<ProviderResult> => {\n return {\n text: 'I am a provider',\n values: {},\n data: {},\n };\n },\n};\n\nexport class StarterService extends Service {\n static serviceType = 'starter';\n capabilityDescription =\n 'This is a starter service which is attached to the agent through the starter plugin.';\n constructor(protected runtime: IAgentRuntime) {\n super(runtime);\n }\n\n static async start(runtime: IAgentRuntime) {\n logger.info(`*** Starting starter service - MODIFIED: ${new Date().toISOString()} ***`);\n const service = new StarterService(runtime);\n return service;\n }\n\n static async stop(runtime: IAgentRuntime) {\n logger.info('*** TESTING DEV MODE - STOP MESSAGE CHANGED! ***');\n // get the service from the runtime\n const service = runtime.getService(StarterService.serviceType);\n if (!service) {\n throw new Error('Starter service not found');\n }\n service.stop();\n }\n\n async stop() {\n logger.info('*** THIRD CHANGE - TESTING FILE WATCHING! ***');\n }\n}\n\nexport const starterPlugin: Plugin = {\n name: 'plugin-starter',\n description: 'Plugin starter for elizaOS',\n config: {\n EXAMPLE_PLUGIN_VARIABLE: process.env.EXAMPLE_PLUGIN_VARIABLE,\n },\n async init(config: Record<string, string>) {\n logger.info('*** TESTING DEV MODE - PLUGIN MODIFIED AND RELOADED! ***');\n try {\n const validatedConfig = await configSchema.parseAsync(config);\n\n // Set all environment variables at once\n for (const [key, value] of Object.entries(validatedConfig)) {\n if (value) process.env[key] = value;\n }\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Invalid plugin configuration: ${error.errors.map((e) => e.message).join(', ')}`\n );\n }\n throw error;\n }\n },\n models: {\n [ModelType.TEXT_SMALL]: async (\n _runtime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n return 'Never gonna give you up, never gonna let you down, never gonna run around and desert you...';\n },\n [ModelType.TEXT_LARGE]: async (\n _runtime,\n {\n prompt,\n stopSequences = [],\n maxTokens = 8192,\n temperature = 0.7,\n frequencyPenalty = 0.7,\n presencePenalty = 0.7,\n }: GenerateTextParams\n ) => {\n return 'Never gonna make you cry, never gonna say goodbye, never gonna tell a lie and hurt you...';\n },\n },\n routes: [\n {\n name: 'hello-world-route',\n path: '/helloworld',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // send a response\n res.json({\n message: 'Hello World!',\n });\n },\n },\n {\n name: 'current-time-route',\n path: '/api/time',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // Return current time in various formats\n const now = new Date();\n res.json({\n timestamp: now.toISOString(),\n unix: Math.floor(now.getTime() / 1000),\n formatted: now.toLocaleString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n },\n },\n ],\n events: {\n MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n VOICE_MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('VOICE_MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_CONNECTED: [\n async (params) => {\n logger.debug('WORLD_CONNECTED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_JOINED: [\n async (params) => {\n logger.debug('WORLD_JOINED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n },\n services: [StarterService],\n actions: [helloWorldAction],\n providers: [helloWorldProvider],\n tests: [StarterPluginTestSuite],\n // dependencies: ['@elizaos/plugin-knowledge'], <--- plugin dependecies go here (if requires another plugin)\n};\n\nexport default starterPlugin;\n","import { type Content, type HandlerCallback } from '@elizaos/core';\n\n/**\n * E2E (End-to-End) Test Suite for ElizaOS Plugins\n * ================================================\n *\n * This file contains end-to-end tests that run within a real ElizaOS runtime environment.\n * Unlike unit tests that test individual components in isolation, e2e tests validate\n * the entire plugin behavior in a production-like environment.\n *\n * NOTE: The tests are properly structured and included in the plugin build.\n * If the test runner is not detecting these tests, it may be looking at the wrong\n * plugin name or there may be a test runner configuration issue. The tests are\n * exported correctly through src/tests.ts and included in the plugin's tests array.\n *\n * HOW E2E TESTS WORK:\n * -------------------\n * 1. Tests are executed by the ElizaOS test runner using `elizaos test e2e`\n * 2. Each test receives a real runtime instance with the plugin loaded\n * 3. Tests can interact with the runtime just like in production\n * 4. Tests throw errors to indicate failure (no assertion library needed)\n *\n * WRITING NEW E2E TESTS:\n * ----------------------\n * 1. Add a new test object to the `tests` array below\n * 2. Each test must have:\n * - `name`: A unique identifier for the test\n * - `fn`: An async function that receives the runtime and performs the test\n *\n * Example structure:\n * ```typescript\n * {\n * name: 'my_new_test',\n * fn: async (runtime) => {\n * // Your test logic here\n * if (someCondition !== expected) {\n * throw new Error('Test failed: reason');\n * }\n * }\n * }\n * ```\n *\n * BEST PRACTICES:\n * ---------------\n * - Test real user scenarios, not implementation details\n * - Use descriptive test names that explain what's being tested\n * - Include clear error messages that help diagnose failures\n * - Test both success and failure paths\n * - Clean up any resources created during tests\n *\n * AVAILABLE RUNTIME METHODS:\n * --------------------------\n * - runtime.getService(type): Get a service instance\n * - runtime.character: Access character configuration\n * - runtime.models: Access AI models\n * - runtime.db: Access database methods\n * - runtime.actions: Access registered actions\n * - runtime.providers: Access registered providers\n *\n * For more details, see the ElizaOS documentation.\n */\n\n// Define a minimal TestSuite interface that matches what's needed\ninterface TestSuite {\n name: string;\n description?: string;\n tests: Array<{\n name: string;\n fn: (runtime: any) => Promise<any>;\n }>;\n}\n\n// Define minimal interfaces for the types we need\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\ninterface Memory {\n entityId: UUID;\n roomId: UUID;\n content: {\n text: string;\n source: string;\n actions?: string[];\n };\n}\n\ninterface State {\n values: Record<string, any>;\n data: Record<string, any>;\n text: string;\n}\n\nexport const StarterPluginTestSuite: TestSuite = {\n name: 'plugin_starter_test_suite',\n description: 'E2E tests for the starter plugin',\n\n tests: [\n /**\n * Basic Plugin Verification Test\n * ------------------------------\n * This test verifies that the plugin is properly loaded and initialized\n * within the runtime environment.\n */\n {\n name: 'example_test',\n fn: async (runtime) => {\n // Test the character name\n if (runtime.character.name !== 'Eliza') {\n throw new Error(\n `Expected character name to be \"Eliza\" but got \"${runtime.character.name}\"`\n );\n }\n // Verify the plugin is loaded properly\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n },\n },\n\n /**\n * Action Registration Test\n * ------------------------\n * Verifies that custom actions are properly registered with the runtime.\n * This is important to ensure actions are available for the agent to use.\n */\n {\n name: 'should_have_hello_world_action',\n fn: async (runtime) => {\n // Access actions through runtime.actions instead of getPlugin\n const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');\n if (!actionExists) {\n throw new Error('Hello world action not found in runtime actions');\n }\n },\n },\n\n /**\n * Hello World Action Response Test\n * ---------------------------------\n * This test demonstrates a complete scenario where:\n * 1. The agent is asked to say \"hello\"\n * 2. The HELLO_WORLD action is triggered\n * 3. The agent responds with text containing \"hello world\"\n *\n * This is a key pattern for testing agent behaviors - you simulate\n * a user message and verify the agent's response.\n */\n {\n name: 'hello_world_action_test',\n fn: async (runtime) => {\n // Create a test message asking the agent to say hello\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'Can you say hello?',\n source: 'test',\n actions: ['HELLO_WORLD'], // Specify which action we expect to trigger\n },\n };\n\n // Create a test state (can include context if needed)\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n let responseText = '';\n let responseReceived = false;\n\n // Find the hello world action in runtime.actions\n const helloWorldAction = runtime.actions?.find((a) => a.name === 'HELLO_WORLD');\n if (!helloWorldAction) {\n throw new Error('Hello world action not found in runtime actions');\n }\n\n // Create a callback that captures the agent's response\n // This simulates how the runtime would handle the action's response\n const callback: HandlerCallback = async (response: Content) => {\n responseReceived = true;\n responseText = response.text || '';\n\n // Verify the response includes the expected action\n if (!response.actions?.includes('HELLO_WORLD')) {\n throw new Error('Response did not include HELLO_WORLD action');\n }\n\n // Return Promise<Memory[]> as required by the HandlerCallback interface\n return Promise.resolve([]);\n };\n\n // Execute the action - this simulates the runtime calling the action\n await helloWorldAction.handler(runtime, testMessage, testState, {}, callback);\n\n // Verify we received a response\n if (!responseReceived) {\n throw new Error('Hello world action did not produce a response');\n }\n\n // Verify the response contains \"hello world\" (case-insensitive)\n if (!responseText.toLowerCase().includes('hello world')) {\n throw new Error(`Expected response to contain \"hello world\" but got: \"${responseText}\"`);\n }\n\n // Success! The agent responded with \"hello world\" as expected\n },\n },\n\n /**\n * Provider Functionality Test\n * ---------------------------\n * Tests that providers can supply data to the agent when needed.\n * Providers are used to fetch external data or compute values.\n */\n {\n name: 'hello_world_provider_test',\n fn: async (runtime) => {\n // Create a test message\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'What can you provide?',\n source: 'test',\n },\n };\n\n // Create a test state\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n // Find the hello world provider in runtime.providers\n const helloWorldProvider = runtime.providers?.find(\n (p) => p.name === 'HELLO_WORLD_PROVIDER'\n );\n if (!helloWorldProvider) {\n throw new Error('Hello world provider not found in runtime providers');\n }\n\n // Test the provider\n const result = await helloWorldProvider.get(runtime, testMessage, testState);\n\n if (result.text !== 'I am a provider') {\n throw new Error(`Expected provider to return \"I am a provider\", got \"${result.text}\"`);\n }\n },\n },\n\n /**\n * Service Lifecycle Test\n * ----------------------\n * Verifies that services can be started, accessed, and stopped properly.\n * Services run background tasks or manage long-lived resources.\n */\n {\n name: 'starter_service_test',\n fn: async (runtime) => {\n // Get the service from the runtime\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n\n // Check service capability description\n if (\n service.capabilityDescription !==\n 'This is a starter service which is attached to the agent through the starter plugin.'\n ) {\n throw new Error('Incorrect service capability description');\n }\n\n // Test service stop method\n await service.stop();\n },\n },\n\n /**\n * ADD YOUR CUSTOM TESTS HERE\n * --------------------------\n * To add a new test:\n *\n * 1. Copy this template:\n * ```typescript\n * {\n * name: 'your_test_name',\n * fn: async (runtime) => {\n * // Setup: Create any test data needed\n *\n * // Action: Perform the operation you want to test\n *\n * // Assert: Check the results\n * if (result !== expected) {\n * throw new Error(`Expected ${expected} but got ${result}`);\n * }\n * }\n * }\n * ```\n *\n * 2. Common test patterns:\n * - Test action responses to specific prompts\n * - Verify provider data under different conditions\n * - Check service behavior during lifecycle events\n * - Validate plugin configuration handling\n * - Test error cases and edge conditions\n *\n * 3. Tips:\n * - Use meaningful variable names\n * - Include helpful error messages\n * - Test one thing per test\n * - Consider both success and failure scenarios\n */\n ],\n};\n\n// Export a default instance of the test suite for the E2E test runner\nexport default StarterPluginTestSuite;\n","import { starterPlugin } from './plugin.ts';\n\nexport { starterPlugin, StarterService } from './plugin.ts';\nexport default starterPlugin;\n"],"mappings":";AACA;AAAA,EAQE;AAAA,EAGA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,SAAS;;;AC2EX,IAAM,yBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,aAAa;AAAA,EAEb,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,YAAI,QAAQ,UAAU,SAAS,SAAS;AACtC,gBAAM,IAAI;AAAA,YACR,kDAAkD,QAAQ,UAAU,IAAI;AAAA,UAC1E;AAAA,QACF;AAEA,cAAM,UAAU,QAAQ,WAAW,SAAS;AAC5C,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,eAAe,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa;AAC1E,YAAI,CAAC,cAAc;AACjB,gBAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,cAAsB;AAAA,UAC1B,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,SAAS,CAAC,aAAa;AAAA;AAAA,UACzB;AAAA,QACF;AAGA,cAAM,YAAmB;AAAA,UACvB,QAAQ,CAAC;AAAA,UACT,MAAM,CAAC;AAAA,UACP,MAAM;AAAA,QACR;AAEA,YAAI,eAAe;AACnB,YAAI,mBAAmB;AAGvB,cAAMA,oBAAmB,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa;AAC9E,YAAI,CAACA,mBAAkB;AACrB,gBAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAIA,cAAM,WAA4B,OAAO,aAAsB;AAC7D,6BAAmB;AACnB,yBAAe,SAAS,QAAQ;AAGhC,cAAI,CAAC,SAAS,SAAS,SAAS,aAAa,GAAG;AAC9C,kBAAM,IAAI,MAAM,6CAA6C;AAAA,UAC/D;AAGA,iBAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,QAC3B;AAGA,cAAMA,kBAAiB,QAAQ,SAAS,aAAa,WAAW,CAAC,GAAG,QAAQ;AAG5E,YAAI,CAAC,kBAAkB;AACrB,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACjE;AAGA,YAAI,CAAC,aAAa,YAAY,EAAE,SAAS,aAAa,GAAG;AACvD,gBAAM,IAAI,MAAM,wDAAwD,YAAY,GAAG;AAAA,QACzF;AAAA,MAGF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,cAAsB;AAAA,UAC1B,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,MAAM;AAAA,YACN,QAAQ;AAAA,UACV;AAAA,QACF;AAGA,cAAM,YAAmB;AAAA,UACvB,QAAQ,CAAC;AAAA,UACT,MAAM,CAAC;AAAA,UACP,MAAM;AAAA,QACR;AAGA,cAAMC,sBAAqB,QAAQ,WAAW;AAAA,UAC5C,CAAC,MAAM,EAAE,SAAS;AAAA,QACpB;AACA,YAAI,CAACA,qBAAoB;AACvB,gBAAM,IAAI,MAAM,qDAAqD;AAAA,QACvE;AAGA,cAAM,SAAS,MAAMA,oBAAmB,IAAI,SAAS,aAAa,SAAS;AAE3E,YAAI,OAAO,SAAS,mBAAmB;AACrC,gBAAM,IAAI,MAAM,uDAAuD,OAAO,IAAI,GAAG;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,UAAU,QAAQ,WAAW,SAAS;AAC5C,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAGA,YACE,QAAQ,0BACR,wFACA;AACA,gBAAM,IAAI,MAAM,0CAA0C;AAAA,QAC5D;AAGA,cAAM,QAAQ,KAAK;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCF;AACF;;;ADpSA,IAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,yBAAyB,EACtB,OAAO,EACP,IAAI,GAAG,yCAAyC,EAChD,SAAS,EACT,UAAU,CAAC,QAAQ;AAClB,QAAI,CAAC,KAAK;AACR,aAAO,KAAK,4DAA4D;AAAA,IAC1E;AACA,WAAO;AAAA,EACT,CAAC;AACL,CAAC;AAgBD,IAAM,mBAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,SAAS,CAAC,SAAS,WAAW;AAAA,EAC9B,aAAa;AAAA,EAEb,UAAU,OACR,UACA,UACA,WACqB;AAErB,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OACP,UACA,SACA,QACA,UACA,UACA,eAC0B;AAC1B,QAAI;AACF,aAAO,KAAK,6BAA6B;AAGzC,YAAM,kBAA2B;AAAA,QAC/B,MAAM;AAAA,QACN,SAAS,CAAC,aAAa;AAAA,QACvB,QAAQ,QAAQ,QAAQ;AAAA,MAC1B;AAGA,UAAI,UAAU;AACZ,cAAM,SAAS,eAAe;AAAA,MAChC;AAGA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,SAAS,CAAC,aAAa;AAAA,UACvB,QAAQ,QAAQ,QAAQ;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,gCAAgC,KAAK;AAClD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU;AAAA,IACR;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS,CAAC,aAAa;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMA,IAAM,qBAA+B;AAAA,EACnC,MAAM;AAAA,EACN,aAAa;AAAA,EAEb,KAAK,OACH,UACA,UACA,WAC4B;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,MAAM,CAAC;AAAA,IACT;AAAA,EACF;AACF;AAEO,IAAM,iBAAN,MAAM,wBAAuB,QAAQ;AAAA,EAI1C,YAAsB,SAAwB;AAC5C,UAAM,OAAO;AADO;AAAA,EAEtB;AAAA,EALA,OAAO,cAAc;AAAA,EACrB,wBACE;AAAA,EAKF,aAAa,MAAM,SAAwB;AACzC,WAAO,KAAK,6CAA4C,oBAAI,KAAK,GAAE,YAAY,CAAC,MAAM;AACtF,UAAM,UAAU,IAAI,gBAAe,OAAO;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,KAAK,SAAwB;AACxC,WAAO,KAAK,kDAAkD;AAE9D,UAAM,UAAU,QAAQ,WAAW,gBAAe,WAAW;AAC7D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,YAAQ,KAAK;AAAA,EACf;AAAA,EAEA,MAAM,OAAO;AACX,WAAO,KAAK,+CAA+C;AAAA,EAC7D;AACF;AAEO,IAAM,gBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,yBAAyB,QAAQ,IAAI;AAAA,EACvC;AAAA,EACA,MAAM,KAAK,QAAgC;AACzC,WAAO,KAAK,0DAA0D;AACtE,QAAI;AACF,YAAM,kBAAkB,MAAM,aAAa,WAAW,MAAM;AAG5D,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,YAAI,MAAO,SAAQ,IAAI,GAAG,IAAI;AAAA,MAChC;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,EAAE,UAAU;AAC/B,cAAM,IAAI;AAAA,UACR,iCAAiC,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QAChF;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,CAAC,UAAU,UAAU,GAAG,OACtB,UACA,EAAE,QAAQ,gBAAgB,CAAC,EAAE,MAC1B;AACH,aAAO;AAAA,IACT;AAAA,IACA,CAAC,UAAU,UAAU,GAAG,OACtB,UACA;AAAA,MACE;AAAA,MACA,gBAAgB,CAAC;AAAA,MACjB,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,IACpB,MACG;AACH,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,OAAO,MAAW,QAAa;AAEtC,YAAI,KAAK;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,OAAO,MAAW,QAAa;AAEtC,cAAM,MAAM,oBAAI,KAAK;AACrB,YAAI,KAAK;AAAA,UACP,WAAW,IAAI,YAAY;AAAA,UAC3B,MAAM,KAAK,MAAM,IAAI,QAAQ,IAAI,GAAI;AAAA,UACrC,WAAW,IAAI,eAAe;AAAA,UAC9B,UAAU,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAAA,QACpD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,kBAAkB;AAAA,MAChB,OAAO,WAAW;AAChB,eAAO,MAAM,iCAAiC;AAE9C,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,IACA,wBAAwB;AAAA,MACtB,OAAO,WAAW;AAChB,eAAO,MAAM,uCAAuC;AAEpD,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,WAAW;AAChB,eAAO,MAAM,gCAAgC;AAE7C,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,WAAW;AAChB,eAAO,MAAM,6BAA6B;AAE1C,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU,CAAC,cAAc;AAAA,EACzB,SAAS,CAAC,gBAAgB;AAAA,EAC1B,WAAW,CAAC,kBAAkB;AAAA,EAC9B,OAAO,CAAC,sBAAsB;AAAA;AAEhC;;;AExRA,IAAO,gBAAQ;","names":["helloWorldAction","helloWorldProvider"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from '@elizaos/core';
|
|
2
2
|
import {
|
|
3
3
|
type Action,
|
|
4
|
+
type ActionResult,
|
|
4
5
|
type Content,
|
|
5
6
|
type GenerateTextParams,
|
|
6
7
|
type HandlerCallback,
|
|
@@ -69,11 +70,11 @@ const helloWorldAction: Action = {
|
|
|
69
70
|
_options: any,
|
|
70
71
|
callback?: HandlerCallback,
|
|
71
72
|
_responses?: Memory[]
|
|
72
|
-
) => {
|
|
73
|
+
): Promise<ActionResult> => {
|
|
73
74
|
try {
|
|
74
75
|
logger.info('Handling HELLO_WORLD action');
|
|
75
76
|
|
|
76
|
-
// Simple response content
|
|
77
|
+
// Simple response content for callback
|
|
77
78
|
const responseContent: Content = {
|
|
78
79
|
text: 'hello world!',
|
|
79
80
|
actions: ['HELLO_WORLD'],
|
|
@@ -85,10 +86,21 @@ const helloWorldAction: Action = {
|
|
|
85
86
|
await callback(responseContent);
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
// Return ActionResult
|
|
90
|
+
return {
|
|
91
|
+
text: 'hello world!',
|
|
92
|
+
success: true,
|
|
93
|
+
data: {
|
|
94
|
+
actions: ['HELLO_WORLD'],
|
|
95
|
+
source: message.content.source,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
89
98
|
} catch (error) {
|
|
90
99
|
logger.error('Error in HELLO_WORLD action:', error);
|
|
91
|
-
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
103
|
+
};
|
|
92
104
|
}
|
|
93
105
|
},
|
|
94
106
|
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@elizaos/cli": "1.2.
|
|
32
|
-
"@elizaos/core": "1.2.
|
|
33
|
-
"@elizaos/plugin-bootstrap": "1.2.
|
|
34
|
-
"@elizaos/plugin-sql": "1.2.
|
|
31
|
+
"@elizaos/cli": "1.2.1",
|
|
32
|
+
"@elizaos/core": "1.2.1",
|
|
33
|
+
"@elizaos/plugin-bootstrap": "1.2.1",
|
|
34
|
+
"@elizaos/plugin-sql": "1.2.1",
|
|
35
35
|
"@tanstack/react-query": "^5.29.0",
|
|
36
36
|
"clsx": "^2.1.1",
|
|
37
37
|
"react": "^18.3.1",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from '@elizaos/core';
|
|
2
2
|
import {
|
|
3
3
|
type Action,
|
|
4
|
+
type ActionResult,
|
|
4
5
|
type Content,
|
|
5
6
|
type GenerateTextParams,
|
|
6
7
|
type HandlerCallback,
|
|
@@ -66,7 +67,7 @@ const helloWorldAction: Action = {
|
|
|
66
67
|
_options: any,
|
|
67
68
|
callback: HandlerCallback,
|
|
68
69
|
_responses: Memory[]
|
|
69
|
-
) => {
|
|
70
|
+
): Promise<ActionResult> => {
|
|
70
71
|
try {
|
|
71
72
|
logger.info('Handling HELLO_WORLD action');
|
|
72
73
|
|
|
@@ -80,10 +81,35 @@ const helloWorldAction: Action = {
|
|
|
80
81
|
// Call back with the hello world message
|
|
81
82
|
await callback(responseContent);
|
|
82
83
|
|
|
83
|
-
return
|
|
84
|
+
return {
|
|
85
|
+
text: 'Sent hello world greeting',
|
|
86
|
+
values: {
|
|
87
|
+
success: true,
|
|
88
|
+
greeted: true,
|
|
89
|
+
},
|
|
90
|
+
data: {
|
|
91
|
+
actionName: 'HELLO_WORLD',
|
|
92
|
+
messageId: message.id,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
},
|
|
95
|
+
success: true,
|
|
96
|
+
};
|
|
84
97
|
} catch (error) {
|
|
85
98
|
logger.error('Error in HELLO_WORLD action:', error);
|
|
86
|
-
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
text: 'Failed to send hello world greeting',
|
|
102
|
+
values: {
|
|
103
|
+
success: false,
|
|
104
|
+
error: 'GREETING_FAILED',
|
|
105
|
+
},
|
|
106
|
+
data: {
|
|
107
|
+
actionName: 'HELLO_WORLD',
|
|
108
|
+
error: error instanceof Error ? error.message : String(error),
|
|
109
|
+
},
|
|
110
|
+
success: false,
|
|
111
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
112
|
+
};
|
|
87
113
|
}
|
|
88
114
|
},
|
|
89
115
|
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"GUIDE.md"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@elizaos/cli": "1.2.
|
|
37
|
-
"@elizaos/core": "1.2.
|
|
36
|
+
"@elizaos/cli": "1.2.1",
|
|
37
|
+
"@elizaos/core": "1.2.1",
|
|
38
38
|
"@elizaos/plugin-redpill": "1.0.3",
|
|
39
|
-
"@elizaos/plugin-sql": "1.2.
|
|
39
|
+
"@elizaos/plugin-sql": "1.2.1",
|
|
40
40
|
"@phala/dstack-sdk": "0.1.11",
|
|
41
41
|
"@solana/web3.js": "1.98.2",
|
|
42
42
|
"viem": "2.30.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "elizaOS CLI - Manage your AI agents and plugins",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -69,14 +69,14 @@
|
|
|
69
69
|
"typescript": "5.8.3",
|
|
70
70
|
"vite": "^6.3.5"
|
|
71
71
|
},
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "227798477b53ad38b01f147ac1a649a5d1c810a3",
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@anthropic-ai/claude-code": "^1.0.35",
|
|
75
75
|
"@anthropic-ai/sdk": "^0.54.0",
|
|
76
76
|
"@clack/prompts": "^0.11.0",
|
|
77
|
-
"@elizaos/core": "1.2.
|
|
78
|
-
"@elizaos/plugin-sql": "1.2.
|
|
79
|
-
"@elizaos/server": "1.2.
|
|
77
|
+
"@elizaos/core": "1.2.1",
|
|
78
|
+
"@elizaos/plugin-sql": "1.2.1",
|
|
79
|
+
"@elizaos/server": "1.2.1",
|
|
80
80
|
"bun": "^1.2.17",
|
|
81
81
|
"chalk": "^5.3.0",
|
|
82
82
|
"chokidar": "^4.0.3",
|
|
@@ -216,10 +216,20 @@ var helloWorldAction = {
|
|
|
216
216
|
if (callback) {
|
|
217
217
|
await callback(responseContent);
|
|
218
218
|
}
|
|
219
|
-
return
|
|
219
|
+
return {
|
|
220
|
+
text: "hello world!",
|
|
221
|
+
success: true,
|
|
222
|
+
data: {
|
|
223
|
+
actions: ["HELLO_WORLD"],
|
|
224
|
+
source: message.content.source
|
|
225
|
+
}
|
|
226
|
+
};
|
|
220
227
|
} catch (error) {
|
|
221
228
|
logger.error("Error in HELLO_WORLD action:", error);
|
|
222
|
-
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
232
|
+
};
|
|
223
233
|
}
|
|
224
234
|
},
|
|
225
235
|
examples: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugin.ts","../src/__tests__/e2e/starter-plugin.ts","../src/index.ts"],"sourcesContent":["import type { Plugin } from '@elizaos/core';\nimport {\n type Action,\n type Content,\n type GenerateTextParams,\n type HandlerCallback,\n type IAgentRuntime,\n type Memory,\n ModelType,\n type Provider,\n type ProviderResult,\n Service,\n type State,\n logger,\n} from '@elizaos/core';\nimport { z } from 'zod';\nimport { StarterPluginTestSuite } from './tests';\n\n/**\n * Defines the configuration schema for a plugin, including the validation rules for the plugin name.\n *\n * @type {import('zod').ZodObject<{ EXAMPLE_PLUGIN_VARIABLE: import('zod').ZodString }>}\n */\nconst configSchema = z.object({\n EXAMPLE_PLUGIN_VARIABLE: z\n .string()\n .min(1, 'Example plugin variable is not provided')\n .optional()\n .transform((val) => {\n if (!val) {\n logger.warn('Example plugin variable is not provided (this is expected)');\n }\n return val;\n }),\n});\n\n/**\n * Example HelloWorld action\n * This demonstrates the simplest possible action structure\n */\n/**\n * Action representing a hello world message.\n * @typedef {Object} Action\n * @property {string} name - The name of the action.\n * @property {string[]} similes - An array of related actions.\n * @property {string} description - A brief description of the action.\n * @property {Function} validate - Asynchronous function to validate the action.\n * @property {Function} handler - Asynchronous function to handle the action and generate a response.\n * @property {Object[]} examples - An array of example inputs and expected outputs for the action.\n */\nconst helloWorldAction: Action = {\n name: 'HELLO_WORLD',\n similes: ['GREET', 'SAY_HELLO'],\n description: 'Responds with a simple hello world message',\n\n validate: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<boolean> => {\n // Always valid\n return true;\n },\n\n handler: async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n _options: any,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ) => {\n try {\n logger.info('Handling HELLO_WORLD action');\n\n // Simple response content\n const responseContent: Content = {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n source: message.content.source,\n };\n\n // Call back with the hello world message if callback is provided\n if (callback) {\n await callback(responseContent);\n }\n\n return responseContent;\n } catch (error) {\n logger.error('Error in HELLO_WORLD action:', error);\n throw error;\n }\n },\n\n examples: [\n [\n {\n name: '{{name1}}',\n content: {\n text: 'Can you say hello?',\n },\n },\n {\n name: '{{name2}}',\n content: {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n },\n },\n ],\n ],\n};\n\n/**\n * Example Hello World Provider\n * This demonstrates the simplest possible provider implementation\n */\nconst helloWorldProvider: Provider = {\n name: 'HELLO_WORLD_PROVIDER',\n description: 'A simple example provider',\n\n get: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<ProviderResult> => {\n return {\n text: 'I am a provider',\n values: {},\n data: {},\n };\n },\n};\n\nexport class StarterService extends Service {\n static serviceType = 'starter';\n capabilityDescription =\n 'This is a starter service which is attached to the agent through the starter plugin.';\n constructor(protected runtime: IAgentRuntime) {\n super(runtime);\n }\n\n static async start(runtime: IAgentRuntime) {\n logger.info(`*** Starting starter service - MODIFIED: ${new Date().toISOString()} ***`);\n const service = new StarterService(runtime);\n return service;\n }\n\n static async stop(runtime: IAgentRuntime) {\n logger.info('*** TESTING DEV MODE - STOP MESSAGE CHANGED! ***');\n // get the service from the runtime\n const service = runtime.getService(StarterService.serviceType);\n if (!service) {\n throw new Error('Starter service not found');\n }\n service.stop();\n }\n\n async stop() {\n logger.info('*** THIRD CHANGE - TESTING FILE WATCHING! ***');\n }\n}\n\nexport const starterPlugin: Plugin = {\n name: 'plugin-starter',\n description: 'Plugin starter for elizaOS',\n config: {\n EXAMPLE_PLUGIN_VARIABLE: process.env.EXAMPLE_PLUGIN_VARIABLE,\n },\n async init(config: Record<string, string>) {\n logger.info('*** TESTING DEV MODE - PLUGIN MODIFIED AND RELOADED! ***');\n try {\n const validatedConfig = await configSchema.parseAsync(config);\n\n // Set all environment variables at once\n for (const [key, value] of Object.entries(validatedConfig)) {\n if (value) process.env[key] = value;\n }\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Invalid plugin configuration: ${error.errors.map((e) => e.message).join(', ')}`\n );\n }\n throw error;\n }\n },\n models: {\n [ModelType.TEXT_SMALL]: async (\n _runtime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n return 'Never gonna give you up, never gonna let you down, never gonna run around and desert you...';\n },\n [ModelType.TEXT_LARGE]: async (\n _runtime,\n {\n prompt,\n stopSequences = [],\n maxTokens = 8192,\n temperature = 0.7,\n frequencyPenalty = 0.7,\n presencePenalty = 0.7,\n }: GenerateTextParams\n ) => {\n return 'Never gonna make you cry, never gonna say goodbye, never gonna tell a lie and hurt you...';\n },\n },\n routes: [\n {\n name: 'hello-world-route',\n path: '/helloworld',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // send a response\n res.json({\n message: 'Hello World!',\n });\n },\n },\n {\n name: 'current-time-route',\n path: '/api/time',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // Return current time in various formats\n const now = new Date();\n res.json({\n timestamp: now.toISOString(),\n unix: Math.floor(now.getTime() / 1000),\n formatted: now.toLocaleString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n },\n },\n ],\n events: {\n MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n VOICE_MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('VOICE_MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_CONNECTED: [\n async (params) => {\n logger.debug('WORLD_CONNECTED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_JOINED: [\n async (params) => {\n logger.debug('WORLD_JOINED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n },\n services: [StarterService],\n actions: [helloWorldAction],\n providers: [helloWorldProvider],\n tests: [StarterPluginTestSuite],\n // dependencies: ['@elizaos/plugin-knowledge'], <--- plugin dependecies go here (if requires another plugin)\n};\n\nexport default starterPlugin;\n","import { type Content, type HandlerCallback } from '@elizaos/core';\n\n/**\n * E2E (End-to-End) Test Suite for ElizaOS Plugins\n * ================================================\n *\n * This file contains end-to-end tests that run within a real ElizaOS runtime environment.\n * Unlike unit tests that test individual components in isolation, e2e tests validate\n * the entire plugin behavior in a production-like environment.\n *\n * NOTE: The tests are properly structured and included in the plugin build.\n * If the test runner is not detecting these tests, it may be looking at the wrong\n * plugin name or there may be a test runner configuration issue. The tests are\n * exported correctly through src/tests.ts and included in the plugin's tests array.\n *\n * HOW E2E TESTS WORK:\n * -------------------\n * 1. Tests are executed by the ElizaOS test runner using `elizaos test e2e`\n * 2. Each test receives a real runtime instance with the plugin loaded\n * 3. Tests can interact with the runtime just like in production\n * 4. Tests throw errors to indicate failure (no assertion library needed)\n *\n * WRITING NEW E2E TESTS:\n * ----------------------\n * 1. Add a new test object to the `tests` array below\n * 2. Each test must have:\n * - `name`: A unique identifier for the test\n * - `fn`: An async function that receives the runtime and performs the test\n *\n * Example structure:\n * ```typescript\n * {\n * name: 'my_new_test',\n * fn: async (runtime) => {\n * // Your test logic here\n * if (someCondition !== expected) {\n * throw new Error('Test failed: reason');\n * }\n * }\n * }\n * ```\n *\n * BEST PRACTICES:\n * ---------------\n * - Test real user scenarios, not implementation details\n * - Use descriptive test names that explain what's being tested\n * - Include clear error messages that help diagnose failures\n * - Test both success and failure paths\n * - Clean up any resources created during tests\n *\n * AVAILABLE RUNTIME METHODS:\n * --------------------------\n * - runtime.getService(type): Get a service instance\n * - runtime.character: Access character configuration\n * - runtime.models: Access AI models\n * - runtime.db: Access database methods\n * - runtime.actions: Access registered actions\n * - runtime.providers: Access registered providers\n *\n * For more details, see the ElizaOS documentation.\n */\n\n// Define a minimal TestSuite interface that matches what's needed\ninterface TestSuite {\n name: string;\n description?: string;\n tests: Array<{\n name: string;\n fn: (runtime: any) => Promise<any>;\n }>;\n}\n\n// Define minimal interfaces for the types we need\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\ninterface Memory {\n entityId: UUID;\n roomId: UUID;\n content: {\n text: string;\n source: string;\n actions?: string[];\n };\n}\n\ninterface State {\n values: Record<string, any>;\n data: Record<string, any>;\n text: string;\n}\n\nexport const StarterPluginTestSuite: TestSuite = {\n name: 'plugin_starter_test_suite',\n description: 'E2E tests for the starter plugin',\n\n tests: [\n /**\n * Basic Plugin Verification Test\n * ------------------------------\n * This test verifies that the plugin is properly loaded and initialized\n * within the runtime environment.\n */\n {\n name: 'example_test',\n fn: async (runtime) => {\n // Test the character name\n if (runtime.character.name !== 'Eliza') {\n throw new Error(\n `Expected character name to be \"Eliza\" but got \"${runtime.character.name}\"`\n );\n }\n // Verify the plugin is loaded properly\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n },\n },\n\n /**\n * Action Registration Test\n * ------------------------\n * Verifies that custom actions are properly registered with the runtime.\n * This is important to ensure actions are available for the agent to use.\n */\n {\n name: 'should_have_hello_world_action',\n fn: async (runtime) => {\n // Access actions through runtime.actions instead of getPlugin\n const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');\n if (!actionExists) {\n throw new Error('Hello world action not found in runtime actions');\n }\n },\n },\n\n /**\n * Hello World Action Response Test\n * ---------------------------------\n * This test demonstrates a complete scenario where:\n * 1. The agent is asked to say \"hello\"\n * 2. The HELLO_WORLD action is triggered\n * 3. The agent responds with text containing \"hello world\"\n *\n * This is a key pattern for testing agent behaviors - you simulate\n * a user message and verify the agent's response.\n */\n {\n name: 'hello_world_action_test',\n fn: async (runtime) => {\n // Create a test message asking the agent to say hello\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'Can you say hello?',\n source: 'test',\n actions: ['HELLO_WORLD'], // Specify which action we expect to trigger\n },\n };\n\n // Create a test state (can include context if needed)\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n let responseText = '';\n let responseReceived = false;\n\n // Find the hello world action in runtime.actions\n const helloWorldAction = runtime.actions?.find((a) => a.name === 'HELLO_WORLD');\n if (!helloWorldAction) {\n throw new Error('Hello world action not found in runtime actions');\n }\n\n // Create a callback that captures the agent's response\n // This simulates how the runtime would handle the action's response\n const callback: HandlerCallback = async (response: Content) => {\n responseReceived = true;\n responseText = response.text || '';\n\n // Verify the response includes the expected action\n if (!response.actions?.includes('HELLO_WORLD')) {\n throw new Error('Response did not include HELLO_WORLD action');\n }\n\n // Return Promise<Memory[]> as required by the HandlerCallback interface\n return Promise.resolve([]);\n };\n\n // Execute the action - this simulates the runtime calling the action\n await helloWorldAction.handler(runtime, testMessage, testState, {}, callback);\n\n // Verify we received a response\n if (!responseReceived) {\n throw new Error('Hello world action did not produce a response');\n }\n\n // Verify the response contains \"hello world\" (case-insensitive)\n if (!responseText.toLowerCase().includes('hello world')) {\n throw new Error(`Expected response to contain \"hello world\" but got: \"${responseText}\"`);\n }\n\n // Success! The agent responded with \"hello world\" as expected\n },\n },\n\n /**\n * Provider Functionality Test\n * ---------------------------\n * Tests that providers can supply data to the agent when needed.\n * Providers are used to fetch external data or compute values.\n */\n {\n name: 'hello_world_provider_test',\n fn: async (runtime) => {\n // Create a test message\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'What can you provide?',\n source: 'test',\n },\n };\n\n // Create a test state\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n // Find the hello world provider in runtime.providers\n const helloWorldProvider = runtime.providers?.find(\n (p) => p.name === 'HELLO_WORLD_PROVIDER'\n );\n if (!helloWorldProvider) {\n throw new Error('Hello world provider not found in runtime providers');\n }\n\n // Test the provider\n const result = await helloWorldProvider.get(runtime, testMessage, testState);\n\n if (result.text !== 'I am a provider') {\n throw new Error(`Expected provider to return \"I am a provider\", got \"${result.text}\"`);\n }\n },\n },\n\n /**\n * Service Lifecycle Test\n * ----------------------\n * Verifies that services can be started, accessed, and stopped properly.\n * Services run background tasks or manage long-lived resources.\n */\n {\n name: 'starter_service_test',\n fn: async (runtime) => {\n // Get the service from the runtime\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n\n // Check service capability description\n if (\n service.capabilityDescription !==\n 'This is a starter service which is attached to the agent through the starter plugin.'\n ) {\n throw new Error('Incorrect service capability description');\n }\n\n // Test service stop method\n await service.stop();\n },\n },\n\n /**\n * ADD YOUR CUSTOM TESTS HERE\n * --------------------------\n * To add a new test:\n *\n * 1. Copy this template:\n * ```typescript\n * {\n * name: 'your_test_name',\n * fn: async (runtime) => {\n * // Setup: Create any test data needed\n *\n * // Action: Perform the operation you want to test\n *\n * // Assert: Check the results\n * if (result !== expected) {\n * throw new Error(`Expected ${expected} but got ${result}`);\n * }\n * }\n * }\n * ```\n *\n * 2. Common test patterns:\n * - Test action responses to specific prompts\n * - Verify provider data under different conditions\n * - Check service behavior during lifecycle events\n * - Validate plugin configuration handling\n * - Test error cases and edge conditions\n *\n * 3. Tips:\n * - Use meaningful variable names\n * - Include helpful error messages\n * - Test one thing per test\n * - Consider both success and failure scenarios\n */\n ],\n};\n\n// Export a default instance of the test suite for the E2E test runner\nexport default StarterPluginTestSuite;\n","import { starterPlugin } from './plugin.ts';\n\nexport { starterPlugin, StarterService } from './plugin.ts';\nexport default starterPlugin;\n"],"mappings":"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","names":["helloWorldAction","helloWorldProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/__tests__/e2e/starter-plugin.ts","../src/index.ts"],"sourcesContent":["import type { Plugin } from '@elizaos/core';\nimport {\n type Action,\n type ActionResult,\n type Content,\n type GenerateTextParams,\n type HandlerCallback,\n type IAgentRuntime,\n type Memory,\n ModelType,\n type Provider,\n type ProviderResult,\n Service,\n type State,\n logger,\n} from '@elizaos/core';\nimport { z } from 'zod';\nimport { StarterPluginTestSuite } from './tests';\n\n/**\n * Defines the configuration schema for a plugin, including the validation rules for the plugin name.\n *\n * @type {import('zod').ZodObject<{ EXAMPLE_PLUGIN_VARIABLE: import('zod').ZodString }>}\n */\nconst configSchema = z.object({\n EXAMPLE_PLUGIN_VARIABLE: z\n .string()\n .min(1, 'Example plugin variable is not provided')\n .optional()\n .transform((val) => {\n if (!val) {\n logger.warn('Example plugin variable is not provided (this is expected)');\n }\n return val;\n }),\n});\n\n/**\n * Example HelloWorld action\n * This demonstrates the simplest possible action structure\n */\n/**\n * Action representing a hello world message.\n * @typedef {Object} Action\n * @property {string} name - The name of the action.\n * @property {string[]} similes - An array of related actions.\n * @property {string} description - A brief description of the action.\n * @property {Function} validate - Asynchronous function to validate the action.\n * @property {Function} handler - Asynchronous function to handle the action and generate a response.\n * @property {Object[]} examples - An array of example inputs and expected outputs for the action.\n */\nconst helloWorldAction: Action = {\n name: 'HELLO_WORLD',\n similes: ['GREET', 'SAY_HELLO'],\n description: 'Responds with a simple hello world message',\n\n validate: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<boolean> => {\n // Always valid\n return true;\n },\n\n handler: async (\n _runtime: IAgentRuntime,\n message: Memory,\n _state: State | undefined,\n _options: any,\n callback?: HandlerCallback,\n _responses?: Memory[]\n ): Promise<ActionResult> => {\n try {\n logger.info('Handling HELLO_WORLD action');\n\n // Simple response content for callback\n const responseContent: Content = {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n source: message.content.source,\n };\n\n // Call back with the hello world message if callback is provided\n if (callback) {\n await callback(responseContent);\n }\n\n // Return ActionResult\n return {\n text: 'hello world!',\n success: true,\n data: {\n actions: ['HELLO_WORLD'],\n source: message.content.source,\n },\n };\n } catch (error) {\n logger.error('Error in HELLO_WORLD action:', error);\n return {\n success: false,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n },\n\n examples: [\n [\n {\n name: '{{name1}}',\n content: {\n text: 'Can you say hello?',\n },\n },\n {\n name: '{{name2}}',\n content: {\n text: 'hello world!',\n actions: ['HELLO_WORLD'],\n },\n },\n ],\n ],\n};\n\n/**\n * Example Hello World Provider\n * This demonstrates the simplest possible provider implementation\n */\nconst helloWorldProvider: Provider = {\n name: 'HELLO_WORLD_PROVIDER',\n description: 'A simple example provider',\n\n get: async (\n _runtime: IAgentRuntime,\n _message: Memory,\n _state: State | undefined\n ): Promise<ProviderResult> => {\n return {\n text: 'I am a provider',\n values: {},\n data: {},\n };\n },\n};\n\nexport class StarterService extends Service {\n static serviceType = 'starter';\n capabilityDescription =\n 'This is a starter service which is attached to the agent through the starter plugin.';\n constructor(protected runtime: IAgentRuntime) {\n super(runtime);\n }\n\n static async start(runtime: IAgentRuntime) {\n logger.info(`*** Starting starter service - MODIFIED: ${new Date().toISOString()} ***`);\n const service = new StarterService(runtime);\n return service;\n }\n\n static async stop(runtime: IAgentRuntime) {\n logger.info('*** TESTING DEV MODE - STOP MESSAGE CHANGED! ***');\n // get the service from the runtime\n const service = runtime.getService(StarterService.serviceType);\n if (!service) {\n throw new Error('Starter service not found');\n }\n service.stop();\n }\n\n async stop() {\n logger.info('*** THIRD CHANGE - TESTING FILE WATCHING! ***');\n }\n}\n\nexport const starterPlugin: Plugin = {\n name: 'plugin-starter',\n description: 'Plugin starter for elizaOS',\n config: {\n EXAMPLE_PLUGIN_VARIABLE: process.env.EXAMPLE_PLUGIN_VARIABLE,\n },\n async init(config: Record<string, string>) {\n logger.info('*** TESTING DEV MODE - PLUGIN MODIFIED AND RELOADED! ***');\n try {\n const validatedConfig = await configSchema.parseAsync(config);\n\n // Set all environment variables at once\n for (const [key, value] of Object.entries(validatedConfig)) {\n if (value) process.env[key] = value;\n }\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Invalid plugin configuration: ${error.errors.map((e) => e.message).join(', ')}`\n );\n }\n throw error;\n }\n },\n models: {\n [ModelType.TEXT_SMALL]: async (\n _runtime,\n { prompt, stopSequences = [] }: GenerateTextParams\n ) => {\n return 'Never gonna give you up, never gonna let you down, never gonna run around and desert you...';\n },\n [ModelType.TEXT_LARGE]: async (\n _runtime,\n {\n prompt,\n stopSequences = [],\n maxTokens = 8192,\n temperature = 0.7,\n frequencyPenalty = 0.7,\n presencePenalty = 0.7,\n }: GenerateTextParams\n ) => {\n return 'Never gonna make you cry, never gonna say goodbye, never gonna tell a lie and hurt you...';\n },\n },\n routes: [\n {\n name: 'hello-world-route',\n path: '/helloworld',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // send a response\n res.json({\n message: 'Hello World!',\n });\n },\n },\n {\n name: 'current-time-route',\n path: '/api/time',\n type: 'GET',\n handler: async (_req: any, res: any) => {\n // Return current time in various formats\n const now = new Date();\n res.json({\n timestamp: now.toISOString(),\n unix: Math.floor(now.getTime() / 1000),\n formatted: now.toLocaleString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n });\n },\n },\n ],\n events: {\n MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n VOICE_MESSAGE_RECEIVED: [\n async (params) => {\n logger.debug('VOICE_MESSAGE_RECEIVED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_CONNECTED: [\n async (params) => {\n logger.debug('WORLD_CONNECTED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n WORLD_JOINED: [\n async (params) => {\n logger.debug('WORLD_JOINED event received');\n // print the keys\n logger.debug(Object.keys(params));\n },\n ],\n },\n services: [StarterService],\n actions: [helloWorldAction],\n providers: [helloWorldProvider],\n tests: [StarterPluginTestSuite],\n // dependencies: ['@elizaos/plugin-knowledge'], <--- plugin dependecies go here (if requires another plugin)\n};\n\nexport default starterPlugin;\n","import { type Content, type HandlerCallback } from '@elizaos/core';\n\n/**\n * E2E (End-to-End) Test Suite for ElizaOS Plugins\n * ================================================\n *\n * This file contains end-to-end tests that run within a real ElizaOS runtime environment.\n * Unlike unit tests that test individual components in isolation, e2e tests validate\n * the entire plugin behavior in a production-like environment.\n *\n * NOTE: The tests are properly structured and included in the plugin build.\n * If the test runner is not detecting these tests, it may be looking at the wrong\n * plugin name or there may be a test runner configuration issue. The tests are\n * exported correctly through src/tests.ts and included in the plugin's tests array.\n *\n * HOW E2E TESTS WORK:\n * -------------------\n * 1. Tests are executed by the ElizaOS test runner using `elizaos test e2e`\n * 2. Each test receives a real runtime instance with the plugin loaded\n * 3. Tests can interact with the runtime just like in production\n * 4. Tests throw errors to indicate failure (no assertion library needed)\n *\n * WRITING NEW E2E TESTS:\n * ----------------------\n * 1. Add a new test object to the `tests` array below\n * 2. Each test must have:\n * - `name`: A unique identifier for the test\n * - `fn`: An async function that receives the runtime and performs the test\n *\n * Example structure:\n * ```typescript\n * {\n * name: 'my_new_test',\n * fn: async (runtime) => {\n * // Your test logic here\n * if (someCondition !== expected) {\n * throw new Error('Test failed: reason');\n * }\n * }\n * }\n * ```\n *\n * BEST PRACTICES:\n * ---------------\n * - Test real user scenarios, not implementation details\n * - Use descriptive test names that explain what's being tested\n * - Include clear error messages that help diagnose failures\n * - Test both success and failure paths\n * - Clean up any resources created during tests\n *\n * AVAILABLE RUNTIME METHODS:\n * --------------------------\n * - runtime.getService(type): Get a service instance\n * - runtime.character: Access character configuration\n * - runtime.models: Access AI models\n * - runtime.db: Access database methods\n * - runtime.actions: Access registered actions\n * - runtime.providers: Access registered providers\n *\n * For more details, see the ElizaOS documentation.\n */\n\n// Define a minimal TestSuite interface that matches what's needed\ninterface TestSuite {\n name: string;\n description?: string;\n tests: Array<{\n name: string;\n fn: (runtime: any) => Promise<any>;\n }>;\n}\n\n// Define minimal interfaces for the types we need\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\ninterface Memory {\n entityId: UUID;\n roomId: UUID;\n content: {\n text: string;\n source: string;\n actions?: string[];\n };\n}\n\ninterface State {\n values: Record<string, any>;\n data: Record<string, any>;\n text: string;\n}\n\nexport const StarterPluginTestSuite: TestSuite = {\n name: 'plugin_starter_test_suite',\n description: 'E2E tests for the starter plugin',\n\n tests: [\n /**\n * Basic Plugin Verification Test\n * ------------------------------\n * This test verifies that the plugin is properly loaded and initialized\n * within the runtime environment.\n */\n {\n name: 'example_test',\n fn: async (runtime) => {\n // Test the character name\n if (runtime.character.name !== 'Eliza') {\n throw new Error(\n `Expected character name to be \"Eliza\" but got \"${runtime.character.name}\"`\n );\n }\n // Verify the plugin is loaded properly\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n },\n },\n\n /**\n * Action Registration Test\n * ------------------------\n * Verifies that custom actions are properly registered with the runtime.\n * This is important to ensure actions are available for the agent to use.\n */\n {\n name: 'should_have_hello_world_action',\n fn: async (runtime) => {\n // Access actions through runtime.actions instead of getPlugin\n const actionExists = runtime.actions?.some((a) => a.name === 'HELLO_WORLD');\n if (!actionExists) {\n throw new Error('Hello world action not found in runtime actions');\n }\n },\n },\n\n /**\n * Hello World Action Response Test\n * ---------------------------------\n * This test demonstrates a complete scenario where:\n * 1. The agent is asked to say \"hello\"\n * 2. The HELLO_WORLD action is triggered\n * 3. The agent responds with text containing \"hello world\"\n *\n * This is a key pattern for testing agent behaviors - you simulate\n * a user message and verify the agent's response.\n */\n {\n name: 'hello_world_action_test',\n fn: async (runtime) => {\n // Create a test message asking the agent to say hello\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'Can you say hello?',\n source: 'test',\n actions: ['HELLO_WORLD'], // Specify which action we expect to trigger\n },\n };\n\n // Create a test state (can include context if needed)\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n let responseText = '';\n let responseReceived = false;\n\n // Find the hello world action in runtime.actions\n const helloWorldAction = runtime.actions?.find((a) => a.name === 'HELLO_WORLD');\n if (!helloWorldAction) {\n throw new Error('Hello world action not found in runtime actions');\n }\n\n // Create a callback that captures the agent's response\n // This simulates how the runtime would handle the action's response\n const callback: HandlerCallback = async (response: Content) => {\n responseReceived = true;\n responseText = response.text || '';\n\n // Verify the response includes the expected action\n if (!response.actions?.includes('HELLO_WORLD')) {\n throw new Error('Response did not include HELLO_WORLD action');\n }\n\n // Return Promise<Memory[]> as required by the HandlerCallback interface\n return Promise.resolve([]);\n };\n\n // Execute the action - this simulates the runtime calling the action\n await helloWorldAction.handler(runtime, testMessage, testState, {}, callback);\n\n // Verify we received a response\n if (!responseReceived) {\n throw new Error('Hello world action did not produce a response');\n }\n\n // Verify the response contains \"hello world\" (case-insensitive)\n if (!responseText.toLowerCase().includes('hello world')) {\n throw new Error(`Expected response to contain \"hello world\" but got: \"${responseText}\"`);\n }\n\n // Success! The agent responded with \"hello world\" as expected\n },\n },\n\n /**\n * Provider Functionality Test\n * ---------------------------\n * Tests that providers can supply data to the agent when needed.\n * Providers are used to fetch external data or compute values.\n */\n {\n name: 'hello_world_provider_test',\n fn: async (runtime) => {\n // Create a test message\n const testMessage: Memory = {\n entityId: '12345678-1234-1234-1234-123456789012' as UUID,\n roomId: '12345678-1234-1234-1234-123456789012' as UUID,\n content: {\n text: 'What can you provide?',\n source: 'test',\n },\n };\n\n // Create a test state\n const testState: State = {\n values: {},\n data: {},\n text: '',\n };\n\n // Find the hello world provider in runtime.providers\n const helloWorldProvider = runtime.providers?.find(\n (p) => p.name === 'HELLO_WORLD_PROVIDER'\n );\n if (!helloWorldProvider) {\n throw new Error('Hello world provider not found in runtime providers');\n }\n\n // Test the provider\n const result = await helloWorldProvider.get(runtime, testMessage, testState);\n\n if (result.text !== 'I am a provider') {\n throw new Error(`Expected provider to return \"I am a provider\", got \"${result.text}\"`);\n }\n },\n },\n\n /**\n * Service Lifecycle Test\n * ----------------------\n * Verifies that services can be started, accessed, and stopped properly.\n * Services run background tasks or manage long-lived resources.\n */\n {\n name: 'starter_service_test',\n fn: async (runtime) => {\n // Get the service from the runtime\n const service = runtime.getService('starter');\n if (!service) {\n throw new Error('Starter service not found');\n }\n\n // Check service capability description\n if (\n service.capabilityDescription !==\n 'This is a starter service which is attached to the agent through the starter plugin.'\n ) {\n throw new Error('Incorrect service capability description');\n }\n\n // Test service stop method\n await service.stop();\n },\n },\n\n /**\n * ADD YOUR CUSTOM TESTS HERE\n * --------------------------\n * To add a new test:\n *\n * 1. Copy this template:\n * ```typescript\n * {\n * name: 'your_test_name',\n * fn: async (runtime) => {\n * // Setup: Create any test data needed\n *\n * // Action: Perform the operation you want to test\n *\n * // Assert: Check the results\n * if (result !== expected) {\n * throw new Error(`Expected ${expected} but got ${result}`);\n * }\n * }\n * }\n * ```\n *\n * 2. Common test patterns:\n * - Test action responses to specific prompts\n * - Verify provider data under different conditions\n * - Check service behavior during lifecycle events\n * - Validate plugin configuration handling\n * - Test error cases and edge conditions\n *\n * 3. Tips:\n * - Use meaningful variable names\n * - Include helpful error messages\n * - Test one thing per test\n * - Consider both success and failure scenarios\n */\n ],\n};\n\n// Export a default instance of the test suite for the E2E test runner\nexport default StarterPluginTestSuite;\n","import { starterPlugin } from './plugin.ts';\n\nexport { starterPlugin, StarterService } from './plugin.ts';\nexport default starterPlugin;\n"],"mappings":";AACA;AAAA,EAQE;AAAA,EAGA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,SAAS;;;AC2EX,IAAM,yBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,aAAa;AAAA,EAEb,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOL;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,YAAI,QAAQ,UAAU,SAAS,SAAS;AACtC,gBAAM,IAAI;AAAA,YACR,kDAAkD,QAAQ,UAAU,IAAI;AAAA,UAC1E;AAAA,QACF;AAEA,cAAM,UAAU,QAAQ,WAAW,SAAS;AAC5C,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,eAAe,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa;AAC1E,YAAI,CAAC,cAAc;AACjB,gBAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,cAAsB;AAAA,UAC1B,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,SAAS,CAAC,aAAa;AAAA;AAAA,UACzB;AAAA,QACF;AAGA,cAAM,YAAmB;AAAA,UACvB,QAAQ,CAAC;AAAA,UACT,MAAM,CAAC;AAAA,UACP,MAAM;AAAA,QACR;AAEA,YAAI,eAAe;AACnB,YAAI,mBAAmB;AAGvB,cAAMA,oBAAmB,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa;AAC9E,YAAI,CAACA,mBAAkB;AACrB,gBAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAIA,cAAM,WAA4B,OAAO,aAAsB;AAC7D,6BAAmB;AACnB,yBAAe,SAAS,QAAQ;AAGhC,cAAI,CAAC,SAAS,SAAS,SAAS,aAAa,GAAG;AAC9C,kBAAM,IAAI,MAAM,6CAA6C;AAAA,UAC/D;AAGA,iBAAO,QAAQ,QAAQ,CAAC,CAAC;AAAA,QAC3B;AAGA,cAAMA,kBAAiB,QAAQ,SAAS,aAAa,WAAW,CAAC,GAAG,QAAQ;AAG5E,YAAI,CAAC,kBAAkB;AACrB,gBAAM,IAAI,MAAM,+CAA+C;AAAA,QACjE;AAGA,YAAI,CAAC,aAAa,YAAY,EAAE,SAAS,aAAa,GAAG;AACvD,gBAAM,IAAI,MAAM,wDAAwD,YAAY,GAAG;AAAA,QACzF;AAAA,MAGF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,cAAsB;AAAA,UAC1B,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,MAAM;AAAA,YACN,QAAQ;AAAA,UACV;AAAA,QACF;AAGA,cAAM,YAAmB;AAAA,UACvB,QAAQ,CAAC;AAAA,UACT,MAAM,CAAC;AAAA,UACP,MAAM;AAAA,QACR;AAGA,cAAMC,sBAAqB,QAAQ,WAAW;AAAA,UAC5C,CAAC,MAAM,EAAE,SAAS;AAAA,QACpB;AACA,YAAI,CAACA,qBAAoB;AACvB,gBAAM,IAAI,MAAM,qDAAqD;AAAA,QACvE;AAGA,cAAM,SAAS,MAAMA,oBAAmB,IAAI,SAAS,aAAa,SAAS;AAE3E,YAAI,OAAO,SAAS,mBAAmB;AACrC,gBAAM,IAAI,MAAM,uDAAuD,OAAO,IAAI,GAAG;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQA;AAAA,MACE,MAAM;AAAA,MACN,IAAI,OAAO,YAAY;AAErB,cAAM,UAAU,QAAQ,WAAW,SAAS;AAC5C,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAGA,YACE,QAAQ,0BACR,wFACA;AACA,gBAAM,IAAI,MAAM,0CAA0C;AAAA,QAC5D;AAGA,cAAM,QAAQ,KAAK;AAAA,MACrB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCF;AACF;;;ADpSA,IAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,yBAAyB,EACtB,OAAO,EACP,IAAI,GAAG,yCAAyC,EAChD,SAAS,EACT,UAAU,CAAC,QAAQ;AAClB,QAAI,CAAC,KAAK;AACR,aAAO,KAAK,4DAA4D;AAAA,IAC1E;AACA,WAAO;AAAA,EACT,CAAC;AACL,CAAC;AAgBD,IAAM,mBAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,SAAS,CAAC,SAAS,WAAW;AAAA,EAC9B,aAAa;AAAA,EAEb,UAAU,OACR,UACA,UACA,WACqB;AAErB,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OACP,UACA,SACA,QACA,UACA,UACA,eAC0B;AAC1B,QAAI;AACF,aAAO,KAAK,6BAA6B;AAGzC,YAAM,kBAA2B;AAAA,QAC/B,MAAM;AAAA,QACN,SAAS,CAAC,aAAa;AAAA,QACvB,QAAQ,QAAQ,QAAQ;AAAA,MAC1B;AAGA,UAAI,UAAU;AACZ,cAAM,SAAS,eAAe;AAAA,MAChC;AAGA,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,SAAS,CAAC,aAAa;AAAA,UACvB,QAAQ,QAAQ,QAAQ;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,gCAAgC,KAAK;AAClD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,MACjE;AAAA,IACF;AAAA,EACF;AAAA,EAEA,UAAU;AAAA,IACR;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS,CAAC,aAAa;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMA,IAAM,qBAA+B;AAAA,EACnC,MAAM;AAAA,EACN,aAAa;AAAA,EAEb,KAAK,OACH,UACA,UACA,WAC4B;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,MAAM,CAAC;AAAA,IACT;AAAA,EACF;AACF;AAEO,IAAM,iBAAN,MAAM,wBAAuB,QAAQ;AAAA,EAI1C,YAAsB,SAAwB;AAC5C,UAAM,OAAO;AADO;AAAA,EAEtB;AAAA,EALA,OAAO,cAAc;AAAA,EACrB,wBACE;AAAA,EAKF,aAAa,MAAM,SAAwB;AACzC,WAAO,KAAK,6CAA4C,oBAAI,KAAK,GAAE,YAAY,CAAC,MAAM;AACtF,UAAM,UAAU,IAAI,gBAAe,OAAO;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,aAAa,KAAK,SAAwB;AACxC,WAAO,KAAK,kDAAkD;AAE9D,UAAM,UAAU,QAAQ,WAAW,gBAAe,WAAW;AAC7D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AACA,YAAQ,KAAK;AAAA,EACf;AAAA,EAEA,MAAM,OAAO;AACX,WAAO,KAAK,+CAA+C;AAAA,EAC7D;AACF;AAEO,IAAM,gBAAwB;AAAA,EACnC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ;AAAA,IACN,yBAAyB,QAAQ,IAAI;AAAA,EACvC;AAAA,EACA,MAAM,KAAK,QAAgC;AACzC,WAAO,KAAK,0DAA0D;AACtE,QAAI;AACF,YAAM,kBAAkB,MAAM,aAAa,WAAW,MAAM;AAG5D,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,YAAI,MAAO,SAAQ,IAAI,GAAG,IAAI;AAAA,MAChC;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,EAAE,UAAU;AAC/B,cAAM,IAAI;AAAA,UACR,iCAAiC,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,QAChF;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,CAAC,UAAU,UAAU,GAAG,OACtB,UACA,EAAE,QAAQ,gBAAgB,CAAC,EAAE,MAC1B;AACH,aAAO;AAAA,IACT;AAAA,IACA,CAAC,UAAU,UAAU,GAAG,OACtB,UACA;AAAA,MACE;AAAA,MACA,gBAAgB,CAAC;AAAA,MACjB,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,IACpB,MACG;AACH,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,OAAO,MAAW,QAAa;AAEtC,YAAI,KAAK;AAAA,UACP,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,OAAO,MAAW,QAAa;AAEtC,cAAM,MAAM,oBAAI,KAAK;AACrB,YAAI,KAAK;AAAA,UACP,WAAW,IAAI,YAAY;AAAA,UAC3B,MAAM,KAAK,MAAM,IAAI,QAAQ,IAAI,GAAI;AAAA,UACrC,WAAW,IAAI,eAAe;AAAA,UAC9B,UAAU,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAAA,QACpD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,kBAAkB;AAAA,MAChB,OAAO,WAAW;AAChB,eAAO,MAAM,iCAAiC;AAE9C,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,IACA,wBAAwB;AAAA,MACtB,OAAO,WAAW;AAChB,eAAO,MAAM,uCAAuC;AAEpD,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,OAAO,WAAW;AAChB,eAAO,MAAM,gCAAgC;AAE7C,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,OAAO,WAAW;AAChB,eAAO,MAAM,6BAA6B;AAE1C,eAAO,MAAM,OAAO,KAAK,MAAM,CAAC;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU,CAAC,cAAc;AAAA,EACzB,SAAS,CAAC,gBAAgB;AAAA,EAC1B,WAAW,CAAC,kBAAkB;AAAA,EAC9B,OAAO,CAAC,sBAAsB;AAAA;AAEhC;;;AExRA,IAAO,gBAAQ;","names":["helloWorldAction","helloWorldProvider"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from '@elizaos/core';
|
|
2
2
|
import {
|
|
3
3
|
type Action,
|
|
4
|
+
type ActionResult,
|
|
4
5
|
type Content,
|
|
5
6
|
type GenerateTextParams,
|
|
6
7
|
type HandlerCallback,
|
|
@@ -69,11 +70,11 @@ const helloWorldAction: Action = {
|
|
|
69
70
|
_options: any,
|
|
70
71
|
callback?: HandlerCallback,
|
|
71
72
|
_responses?: Memory[]
|
|
72
|
-
) => {
|
|
73
|
+
): Promise<ActionResult> => {
|
|
73
74
|
try {
|
|
74
75
|
logger.info('Handling HELLO_WORLD action');
|
|
75
76
|
|
|
76
|
-
// Simple response content
|
|
77
|
+
// Simple response content for callback
|
|
77
78
|
const responseContent: Content = {
|
|
78
79
|
text: 'hello world!',
|
|
79
80
|
actions: ['HELLO_WORLD'],
|
|
@@ -85,10 +86,21 @@ const helloWorldAction: Action = {
|
|
|
85
86
|
await callback(responseContent);
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
|
|
89
|
+
// Return ActionResult
|
|
90
|
+
return {
|
|
91
|
+
text: 'hello world!',
|
|
92
|
+
success: true,
|
|
93
|
+
data: {
|
|
94
|
+
actions: ['HELLO_WORLD'],
|
|
95
|
+
source: message.content.source,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
89
98
|
} catch (error) {
|
|
90
99
|
logger.error('Error in HELLO_WORLD action:', error);
|
|
91
|
-
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
103
|
+
};
|
|
92
104
|
}
|
|
93
105
|
},
|
|
94
106
|
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@elizaos/cli": "1.2.
|
|
32
|
-
"@elizaos/core": "1.2.
|
|
33
|
-
"@elizaos/plugin-bootstrap": "1.2.
|
|
34
|
-
"@elizaos/plugin-sql": "1.2.
|
|
31
|
+
"@elizaos/cli": "1.2.1",
|
|
32
|
+
"@elizaos/core": "1.2.1",
|
|
33
|
+
"@elizaos/plugin-bootstrap": "1.2.1",
|
|
34
|
+
"@elizaos/plugin-sql": "1.2.1",
|
|
35
35
|
"@tanstack/react-query": "^5.29.0",
|
|
36
36
|
"clsx": "^2.1.1",
|
|
37
37
|
"react": "^18.3.1",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from '@elizaos/core';
|
|
2
2
|
import {
|
|
3
3
|
type Action,
|
|
4
|
+
type ActionResult,
|
|
4
5
|
type Content,
|
|
5
6
|
type GenerateTextParams,
|
|
6
7
|
type HandlerCallback,
|
|
@@ -66,7 +67,7 @@ const helloWorldAction: Action = {
|
|
|
66
67
|
_options: any,
|
|
67
68
|
callback: HandlerCallback,
|
|
68
69
|
_responses: Memory[]
|
|
69
|
-
) => {
|
|
70
|
+
): Promise<ActionResult> => {
|
|
70
71
|
try {
|
|
71
72
|
logger.info('Handling HELLO_WORLD action');
|
|
72
73
|
|
|
@@ -80,10 +81,35 @@ const helloWorldAction: Action = {
|
|
|
80
81
|
// Call back with the hello world message
|
|
81
82
|
await callback(responseContent);
|
|
82
83
|
|
|
83
|
-
return
|
|
84
|
+
return {
|
|
85
|
+
text: 'Sent hello world greeting',
|
|
86
|
+
values: {
|
|
87
|
+
success: true,
|
|
88
|
+
greeted: true,
|
|
89
|
+
},
|
|
90
|
+
data: {
|
|
91
|
+
actionName: 'HELLO_WORLD',
|
|
92
|
+
messageId: message.id,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
},
|
|
95
|
+
success: true,
|
|
96
|
+
};
|
|
84
97
|
} catch (error) {
|
|
85
98
|
logger.error('Error in HELLO_WORLD action:', error);
|
|
86
|
-
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
text: 'Failed to send hello world greeting',
|
|
102
|
+
values: {
|
|
103
|
+
success: false,
|
|
104
|
+
error: 'GREETING_FAILED',
|
|
105
|
+
},
|
|
106
|
+
data: {
|
|
107
|
+
actionName: 'HELLO_WORLD',
|
|
108
|
+
error: error instanceof Error ? error.message : String(error),
|
|
109
|
+
},
|
|
110
|
+
success: false,
|
|
111
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
112
|
+
};
|
|
87
113
|
}
|
|
88
114
|
},
|
|
89
115
|
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"GUIDE.md"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@elizaos/cli": "1.2.
|
|
37
|
-
"@elizaos/core": "1.2.
|
|
36
|
+
"@elizaos/cli": "1.2.1",
|
|
37
|
+
"@elizaos/core": "1.2.1",
|
|
38
38
|
"@elizaos/plugin-redpill": "1.0.3",
|
|
39
|
-
"@elizaos/plugin-sql": "1.2.
|
|
39
|
+
"@elizaos/plugin-sql": "1.2.1",
|
|
40
40
|
"@phala/dstack-sdk": "0.1.11",
|
|
41
41
|
"@solana/web3.js": "1.98.2",
|
|
42
42
|
"viem": "2.30.1",
|