mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 16:01:54 +00:00
Merge pull request #174 from PR0M3TH3AN/agents/weekly/smoke-agent-5242811211812357470
feat: implement smoke-agent harness and run cycle
This commit is contained in:
2 files changed
+192
No files matched your search
@@ -0,0 +1,177 @@
|
||||
import { Relay, useWebSocketImplementation } from 'nostr-tools/relay';
|
||||
import { generateSecretKey, finalizeEvent, getPublicKey } from 'nostr-tools/pure';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { spawn } from 'node:child_process';
|
||||
import WebSocket from 'ws';
|
||||
|
||||
useWebSocketImplementation(WebSocket);
|
||||
|
||||
// --- Configuration ---
|
||||
const ARGS = process.argv.slice(2);
|
||||
const getArg = (key) => {
|
||||
const idx = ARGS.findIndex(a => a.startsWith(`--${key}=`));
|
||||
if (idx !== -1) return ARGS[idx].split('=')[1];
|
||||
const flagIdx = ARGS.indexOf(`--${key}`);
|
||||
if (flagIdx !== -1 && ARGS[flagIdx + 1] && !ARGS[flagIdx + 1].startsWith('--')) return ARGS[flagIdx + 1];
|
||||
return null;
|
||||
};
|
||||
const hasArg = (key) => ARGS.includes(`--${key}`);
|
||||
|
||||
const RELAYS = (getArg('relays') || process.env.RELAY_URLS || '').split(',').filter(Boolean);
|
||||
const SERVE_CMD = getArg('serve') || 'npx';
|
||||
const CONFIRM_PUBLIC = hasArg('confirm-public');
|
||||
const OUT_DIR = getArg('out') || 'artifacts';
|
||||
|
||||
// --- Logging ---
|
||||
const LOG_FILE = path.join(OUT_DIR, `smoke-${new Date().toISOString().replace(/[:.]/g, '-')}.log`);
|
||||
const JSON_FILE = path.join(OUT_DIR, `smoke-${new Date().toISOString().split('T')[0]}.json`);
|
||||
|
||||
if (!fs.existsSync(OUT_DIR)) fs.mkdirSync(OUT_DIR, { recursive: true });
|
||||
|
||||
function log(msg) {
|
||||
const ts = new Date().toISOString();
|
||||
const line = `[${ts}] ${msg}`;
|
||||
console.log(line);
|
||||
fs.appendFileSync(LOG_FILE, line + '\n');
|
||||
}
|
||||
|
||||
// --- Helpers ---
|
||||
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
async function waitForServer(url, timeoutMs = 10000) {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeoutMs) {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
if (res.ok) return true;
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
await sleep(500);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- Main ---
|
||||
async function main() {
|
||||
log('Starting Smoke Test Agent...');
|
||||
log(`Config: RELAYS=${RELAYS.join(',')}, SERVE=${SERVE_CMD}, OUT=${OUT_DIR}`);
|
||||
|
||||
if (RELAYS.length === 0) {
|
||||
log('ERROR: No relays specified. Use --relays or RELAY_URLS.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const results = {
|
||||
timestamp: new Date().toISOString(),
|
||||
steps: [],
|
||||
success: false
|
||||
};
|
||||
|
||||
let serverProcess = null;
|
||||
|
||||
try {
|
||||
// 1. Start Server
|
||||
if (SERVE_CMD !== 'none') {
|
||||
log('Step 1: Starting local server...');
|
||||
const port = 8000;
|
||||
if (SERVE_CMD === 'npx') {
|
||||
serverProcess = spawn('npx', ['serve', 'dist', '-p', String(port)], { stdio: 'ignore', shell: true });
|
||||
} else if (SERVE_CMD === 'python') {
|
||||
serverProcess = spawn('python3', ['-m', 'http.server', String(port), '-d', 'dist'], { stdio: 'ignore', shell: true });
|
||||
}
|
||||
|
||||
const serverUrl = `http://localhost:${port}`;
|
||||
log(`Waiting for server at ${serverUrl}...`);
|
||||
const ready = await waitForServer(serverUrl);
|
||||
if (!ready) {
|
||||
throw new Error('Server failed to start within timeout');
|
||||
}
|
||||
log('Server is ready.');
|
||||
results.steps.push({ name: 'start-server', status: 'ok', details: `Started ${SERVE_CMD} on port ${port}` });
|
||||
} else {
|
||||
log('Step 1: Skipping server start (none selected).');
|
||||
results.steps.push({ name: 'start-server', status: 'skipped' });
|
||||
}
|
||||
|
||||
// 2. Connect to Relay
|
||||
log(`Step 2: Connecting to relay ${RELAYS[0]}...`);
|
||||
const relay = await Relay.connect(RELAYS[0]);
|
||||
log(`Connected to ${RELAYS[0]}`);
|
||||
results.steps.push({ name: 'connect-relay', status: 'ok', details: RELAYS[0] });
|
||||
|
||||
// 3. Generate Identity
|
||||
log('Step 3: Generating ephemeral identity...');
|
||||
const sk = generateSecretKey();
|
||||
const pk = getPublicKey(sk);
|
||||
log(`Pubkey: ${pk}`);
|
||||
results.steps.push({ name: 'generate-identity', status: 'ok', details: pk });
|
||||
|
||||
// 4. Publish Event
|
||||
log('Step 4: Publishing smoke test event...');
|
||||
const eventTemplate = {
|
||||
kind: 1,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
tags: [['t', 'smoke-test']],
|
||||
content: `Smoke test run at ${new Date().toISOString()}`,
|
||||
};
|
||||
const event = finalizeEvent(eventTemplate, sk);
|
||||
await relay.publish(event);
|
||||
log(`Published event: ${event.id}`);
|
||||
results.steps.push({ name: 'publish-event', status: 'ok', details: event.id });
|
||||
|
||||
// 5. Verify Event
|
||||
log('Step 5: Verifying event read-back...');
|
||||
const sub = relay.subscribe([
|
||||
{ ids: [event.id] },
|
||||
], {
|
||||
onevent(evt) {
|
||||
log(`Received event: ${evt.id}`);
|
||||
if (evt.id === event.id) {
|
||||
log('Verification SUCCESS: Event ID matches.');
|
||||
results.steps.push({ name: 'verify-event', status: 'ok', details: 'Event retrieved and matched' });
|
||||
sub.close();
|
||||
}
|
||||
},
|
||||
oneose() {
|
||||
sub.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait for event
|
||||
let attempts = 0;
|
||||
let verified = false;
|
||||
while (attempts < 10) {
|
||||
await sleep(1000);
|
||||
const found = results.steps.find(s => s.name === 'verify-event');
|
||||
if (found) {
|
||||
verified = true;
|
||||
break;
|
||||
}
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (!verified) {
|
||||
throw new Error('Verification failed: Event not received within timeout.');
|
||||
}
|
||||
|
||||
results.success = true;
|
||||
relay.close();
|
||||
|
||||
} catch (err) {
|
||||
log(`ERROR: ${err.message}`);
|
||||
results.error = err.message;
|
||||
results.success = false;
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
if (serverProcess) {
|
||||
log('Stopping server...');
|
||||
serverProcess.kill();
|
||||
}
|
||||
fs.writeFileSync(JSON_FILE, JSON.stringify(results, null, 2));
|
||||
log(`Artifacts written to ${OUT_DIR}`);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,15 @@
|
||||
# smoke-agent completed
|
||||
|
||||
Smoke test harness implemented in `scripts/agent/smoke-test.mjs`.
|
||||
Verified:
|
||||
- Server start (`npx serve` or `python`)
|
||||
- Relay connection (wss://relay.damus.io)
|
||||
- Ephemeral identity generation
|
||||
- Event publication
|
||||
- Event verification (read-back)
|
||||
|
||||
Artifacts generated (but not committed):
|
||||
- artifacts/smoke-*.log
|
||||
- artifacts/smoke-*.json
|
||||
|
||||
Memory retrieved and stored successfully.
|
||||
Reference in new issue
Block a user