Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integration tests fixes + library improvements #1177

Merged
merged 14 commits into from
Dec 18, 2024
Merged
2 changes: 1 addition & 1 deletion .github/workflows/integrationTests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
push:
branches:
- "*"
pull_request_target:
pull_request:
branches:
- "*"
jobs:
Expand Down
3 changes: 2 additions & 1 deletion agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export const wait = (minTime: number = 1000, maxTime: number = 3000) => {

const logFetch = async (url: string, options: any) => {
elizaLogger.debug(`Fetching ${url}`);
elizaLogger.debug(JSON.stringify(options, null, 2));
// Disabled to avoid disclosure of sensitive information such as API keys
// elizaLogger.debug(JSON.stringify(options, null, 2));
return fetch(url, options);
};

Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
"typedoc": "0.26.11",
"typescript": "5.6.3",
"vite": "5.4.11",
"vitest": "2.1.5",
"zx": "^8.2.4"
"vitest": "2.1.5"
},
"pnpm": {
"overrides": {
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ class ElizaLogger {
}

export const elizaLogger = new ElizaLogger();
elizaLogger.clear();
elizaLogger.closeByNewLine = true;
elizaLogger.useIcons = true;

Expand Down
40,333 changes: 22,613 additions & 17,720 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

37 changes: 14 additions & 23 deletions tests/test1.mjs
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
import { $, chalk } from 'zx';
import assert from 'assert';
import {
startAgent,
stopAgent,
send
send,
log,
logError,
runIntegrationTest
} from "./testLibrary.mjs";
import { stringToUuid } from '../packages/core/dist/index.js'

export const DEFAULT_CHARACTER = "trump"
export const DEFAULT_AGENT_ID = stringToUuid(DEFAULT_CHARACTER ?? uuidv4());

async function test1() {
const proc = await startAgent();
try {
async function helloTrump() {
const reply = await send("Hi");
assert(reply.length > 10);
}

const reply = await send("Hi");
assert(reply.length > 10);
console.log(chalk.green('✓ Test 1 passed'));
} catch (error) {
console.error(chalk.red(`✗ Test 1 failed: ${error.message}`));
process.exit(1);
} finally {
await stopAgent(proc);
}
async function coinbaseTest() {
// TODO
}

const testSuite = [helloTrump]; // Add tests here
try {
await test1();
for (const test of testSuite) await runIntegrationTest(test);
} catch (error) {
console.error(chalk.red(`Error: ${error.message}`));
logError(error);
process.exit(1);
}
}
117 changes: 81 additions & 36 deletions tests/testLibrary.mjs
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
import { $, fs, path, chalk } from 'zx';
import { DEFAULT_AGENT_ID, DEFAULT_CHARACTER } from './test1.mjs';
import { spawn } from 'node:child_process';
$.verbose = false; // Suppress command output unless there's an error
import { spawn } from "node:child_process";
import { stringToUuid } from "../packages/core/dist/index.js";
import path from "path";

export const DEFAULT_CHARACTER = "trump"
export const DEFAULT_AGENT_ID = stringToUuid(DEFAULT_CHARACTER ?? uuidv4());

function projectRoot() {
return path.join(import.meta.dirname, "..");
}

function log(message) {
console.log(message);
}

function logError(error) {
log("ERROR: " + error.message);
log(error); // Print stack trace
}

async function runProcess(command, args = [], directory = projectRoot()) {
try {
const result = await $`cd ${directory} && ${command} ${args}`;
throw new Exception("Not implemented yet"); // TODO
// const result = await $`cd ${directory} && ${command} ${args}`;
return result.stdout.trim();
} catch (error) {
throw new Error(`Command failed: ${error.message}`);
}
}

async function installProjectDependencies() {
console.log(chalk.blue('Installing dependencies...'));
log('Installing dependencies...');
return await runProcess('pnpm', ['install', '-r']);
}

async function buildProject() {
console.log(chalk.blue('Building project...'));
log('Building project...');
return await runProcess('pnpm', ['build']);
}

Expand All @@ -34,50 +46,81 @@ async function writeEnvFile(entries) {
}

async function startAgent(character = DEFAULT_CHARACTER) {
console.log(chalk.blue(`Starting agent for character: ${character}`));
const proc = spawn('pnpm', ['start', `--character=characters/${character}.character.json`, '--non-interactive'], { shell: true, "stdio": "inherit" });
log(`proc=${JSON.stringify(proc)}`);

// Wait for server to be ready
await new Promise(resolve => setTimeout(resolve, 20000));
log(`Starting agent for character: ${character}`);
const proc = spawn("node", ["--loader", "ts-node/esm", "src/index.ts", "--isRoot", `--character=characters/${character}.character.json`, "--non-interactive"], {
cwd: path.join(projectRoot(), "agent"),
shell: false,
stdio: "inherit"
});
const startTime = Date.now();
while (true) {
try {
const response = await fetch("http://127.0.0.1:3000/", {method: "GET"});
if (response.ok) break;
} catch (error) {}
if (Date.now() - startTime > 120000) {
throw new Error("Timeout waiting for process to start");
} else {
await sleep(1000);
}
}
await sleep(1000);
return proc;
}

async function stopAgent(proc) {
console.log(chalk.blue('Stopping agent...'));
proc.kill('SIGTERM')
log("Stopping agent..." + JSON.stringify(proc.pid));
proc.kill();
const startTime = Date.now();
while (true) {
if (proc.killed) break;
if (Date.now() - startTime > 60000) {
throw new Error("Timeout waiting for the process to terminate");
}
await sleep(1000);
}
await sleep(1000);
}

async function send(message) {
const endpoint = `http://127.0.0.1:3000/${DEFAULT_AGENT_ID}/message`;
const payload = {
text: message,
userId: "user",
userName: "User"
};
async function sleep(ms) {
await new Promise(resolve => setTimeout(resolve, ms));
}

async function sendPostRequest(url, method, payload) {
try {
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
const response = await fetch(url, {
method: method,
headers: {"Content-Type": "application/json"},
body: JSON.stringify(payload)
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
return data[0].text;
} catch (error) {
throw new Error(`Failed to send message: ${error.message}`);
}
}

function log(message) {
console.log(message);
async function send(message) {
const url = `http://127.0.0.1:3000/${DEFAULT_AGENT_ID}/message`;
return await sendPostRequest(url, "POST", {
text: message,
userId: "user",
userName: "User"
});
}

async function runIntegrationTest(fn) {
const proc = await startAgent();
try {
await fn();
log("✓ Test passed");
} catch (error) {
log("✗ Test failed");
logError(error);
} finally {
await stopAgent(proc);
}
}

export {
Expand All @@ -89,5 +132,7 @@ export {
startAgent,
stopAgent,
send,
log
}
runIntegrationTest,
log,
logError
}
Loading