UNPKG

create-eliza

Version:

Initialize an Eliza project

317 lines (312 loc) 9.38 kB
import { createRequire } from 'module'; const require = createRequire(import.meta.url); import { loadProject } from "./chunk-JCYGEYAL.js"; import { AgentServer, jsonToCharacter, loadCharacterTryPath, promptForEnvVars } from "./chunk-KIQMDR2R.js"; import { require_main } from "./chunk-ZMJ3QLUC.js"; import { handleError } from "./chunk-6UADHYNA.js"; import { AgentRuntime, logger, settings, stringToUuid } from "./chunk-MQCRBT4U.js"; import { Command } from "./chunk-CKY7YPIS.js"; import { __toESM } from "./chunk-WCMDOJQK.js"; // src/testRunner.ts var TestRunner = class { runtime; projectAgent; stats; constructor(runtime, projectAgent) { this.runtime = runtime; this.projectAgent = projectAgent; this.stats = { total: 0, passed: 0, failed: 0, skipped: 0 }; } /** * Runs a test suite * @param suite The test suite to run */ async runTestSuite(suite) { logger.info(` Running test suite: ${suite.name}`); for (const test2 of suite.tests) { this.stats.total++; try { logger.info(` Running test: ${test2.name}`); await test2.fn(this.runtime); this.stats.passed++; logger.success(` \u2713 ${test2.name}`); } catch (error) { this.stats.failed++; logger.error(` \u2717 ${test2.name}`); logger.error(` ${error.message}`); } } } /** * Runs project agent tests */ async runProjectTests(options) { if (!this.projectAgent?.tests || options.skipProjectTests) { return; } logger.info("\nRunning project tests..."); const testSuites = Array.isArray(this.projectAgent.tests) ? this.projectAgent.tests : [this.projectAgent.tests]; for (const suite of testSuites) { if (!suite) { continue; } if (options.filter && !suite.name.includes(options.filter)) { this.stats.skipped++; continue; } await this.runTestSuite(suite); } } /** * Runs plugin tests */ async runPluginTests(options) { if (options.skipPlugins) { return; } logger.info("\nRunning plugin tests..."); const plugins = this.runtime.plugins || []; for (const plugin of plugins) { try { const pluginTests = plugin.tests; if (!pluginTests) { continue; } const testSuites = Array.isArray(pluginTests) ? pluginTests : [pluginTests]; for (const suite of testSuites) { if (!suite) { continue; } if (options.filter && !suite.name.includes(options.filter)) { this.stats.skipped++; continue; } await this.runTestSuite(suite); } } catch (error) { logger.error(`Error running tests for plugin ${plugin.name}:`, error); this.stats.failed++; } } } /** * Runs all tests in the project * @param options Test options */ async runTests(options = {}) { await this.runProjectTests(options); await this.runPluginTests(options); return this.stats; } }; // src/commands/test.ts var dotenv = __toESM(require_main(), 1); import * as net from "node:net"; import path from "node:path"; import * as os from "node:os"; import * as fs from "node:fs"; async function checkPortAvailable(port) { return new Promise((resolve) => { const server = net.createServer(); server.once("error", () => { resolve(false); }); server.once("listening", () => { server.close(); resolve(true); }); server.listen(port); }); } async function startAgent(character, server, init, plugins = []) { character.id ??= stringToUuid(character.name); const runtime = new AgentRuntime({ character, plugins }); if (init) { await init(runtime); } await runtime.initialize(); server.registerAgent(runtime); logger.debug(`Started ${runtime.character.name} as ${runtime.agentId}`); return runtime; } var runAgentTests = async (options) => { const runtimes = []; const projectAgents = []; const homeDir = os.homedir(); const elizaDir = path.join(homeDir, ".eliza"); const elizaDbDir = path.join(elizaDir, "db"); const envFilePath = path.join(elizaDir, ".env"); if (!fs.existsSync(elizaDir)) { fs.mkdirSync(elizaDir, { recursive: true }); logger.info(`Created directory: ${elizaDir}`); } if (!fs.existsSync(elizaDbDir)) { fs.mkdirSync(elizaDbDir, { recursive: true }); logger.info(`Created database directory: ${elizaDbDir}`); } process.env.PGLITE_DATA_DIR = elizaDbDir; logger.info(`Using database directory: ${elizaDbDir}`); if (fs.existsSync(envFilePath)) { dotenv.config({ path: envFilePath }); } try { await promptForEnvVars("pglite"); } catch (error) { logger.warn(`Error configuring database: ${error}`); } const postgresUrl = process.env.POSTGRES_URL; logger.info("Creating server instance..."); const server = new AgentServer({ dataDir: elizaDbDir, postgresUrl }); logger.info("Server instance created"); logger.info("Setting up server properties..."); server.startAgent = async (character) => { logger.info(`Starting agent for character ${character.name}`); return startAgent(character, server); }; server.loadCharacterTryPath = loadCharacterTryPath; server.jsonToCharacter = jsonToCharacter; logger.info("Server properties set up"); let serverPort = options.port || Number.parseInt(settings.SERVER_PORT || "3000"); logger.info("Loading project from current directory:", process.cwd()); let project; try { project = await loadProject(process.cwd()); logger.info("Project loaded successfully:", JSON.stringify(project, null, 2)); if (!project || !project.agents || project.agents.length === 0) { throw new Error("No agents found in project configuration"); } logger.info(`Found ${project.agents.length} agents in project configuration`); } catch (error) { logger.error("Error loading project:", error); if (error instanceof Error) { logger.error("Error details:", error.message); logger.error("Stack trace:", error.stack); } throw error; } logger.info("Checking port availability..."); while (!await checkPortAvailable(serverPort)) { logger.warn(`Port ${serverPort} is in use, trying ${serverPort + 1}`); serverPort++; } logger.info(`Using port ${serverPort}`); logger.info("Starting server..."); try { await server.start(serverPort); logger.info("Server started successfully"); } catch (error) { logger.error("Error starting server:", error); if (error instanceof Error) { logger.error("Error details:", error.message); logger.error("Stack trace:", error.stack); } throw error; } try { logger.info(`Found ${project.agents.length} agents in project`); for (const agent of project.agents) { try { logger.info(`Starting agent: ${agent.character.name}`); const runtime = await startAgent( agent.character, server, agent.init, agent.plugins || [] ); runtimes.push(runtime); projectAgents.push(agent); await new Promise((resolve) => setTimeout(resolve, 500)); } catch (agentError) { logger.error( `Error starting agent ${agent.character.name}: ${agentError}` ); } } if (runtimes.length === 0) { throw new Error("Failed to start any agents from project"); } logger.info(`Successfully started ${runtimes.length} agents from project`); let totalFailed = 0; for (let i = 0; i < runtimes.length; i++) { const runtime = runtimes[i]; const projectAgent = projectAgents[i]; logger.info(`Running tests for agent: ${runtime.character.name}`); const testRunner = new TestRunner(runtime, projectAgent); const results = await testRunner.runTests({ filter: options.plugin, skipPlugins: options.skipPlugins, skipProjectTests: options.skipProjectTests }); totalFailed += results.failed; } await server.stop(); process.exit(totalFailed > 0 ? 1 : 0); } catch (error) { logger.error("Error running tests:", error); if (error instanceof Error) { logger.error("Error details:", error.message); logger.error("Stack trace:", error.stack); } await server.stop(); process.exit(1); } }; var test = new Command().name("test").description("Run tests for Eliza agent plugins").option( "-p, --port <port>", "Port to listen on", (val) => Number.parseInt(val) ).option("-P, --plugin <name>", "Name of plugin to test").option("--skip-plugins", "Skip plugin tests").option("--skip-project-tests", "Skip project tests").action(async (options) => { logger.info("Starting test command..."); logger.info("Command options:", options); try { logger.info("Running agent tests..."); await runAgentTests(options); } catch (error) { logger.error("Error running tests:", error); if (error instanceof Error) { logger.error("Error details:", error.message); logger.error("Stack trace:", error.stack); } handleError(error); } }); function registerCommand(cli) { return cli.addCommand(test); } export { test, registerCommand }; //# sourceMappingURL=chunk-W2LX64UQ.js.map