Skip to content

Commit 77d686c

Browse files
author
LoreResearch
committed
hardening: isolate lore research sweep failures
1 parent e484a22 commit 77d686c

1 file changed

Lines changed: 76 additions & 13 deletions

File tree

index.ts

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,113 @@ import { printReport } from "./src/output/printer.js";
55
import { saveReport, getAllReports } from "./src/output/store.js";
66
import { config } from "./src/lib/config.js";
77
import { log } from "./src/lib/logger.js";
8+
import type { ResearchReport } from "./src/lib/types.js";
89

9-
async function researchProtocol(protocolId: string): Promise<void> {
10+
function sleep(ms: number): Promise<void> {
11+
return new Promise((resolve) => setTimeout(resolve, ms));
12+
}
13+
14+
async function researchProtocol(protocolId: string): Promise<ResearchReport | null> {
1015
const protocols = getAllProtocols();
1116
const protocol = protocols.find((p) => p.id === protocolId);
12-
if (!protocol) { log.warn(`Protocol not found: ${protocolId}`); return; }
17+
if (!protocol) {
18+
log.warn(`Protocol not found: ${protocolId}`);
19+
return null;
20+
}
1321

1422
log.info(`Researching ${protocol.name}...`);
1523
const metrics = await fetchProtocolMetrics(protocol).catch((e) => {
16-
log.warn(`Metrics fetch failed for ${protocol.name}:`, e.message);
24+
const message = e instanceof Error ? e.message : String(e);
25+
log.warn(`Metrics fetch failed for ${protocol.name}:`, message);
26+
return null;
27+
});
28+
29+
const report = await runLoreAgent(protocol, metrics).catch((e) => {
30+
const message = e instanceof Error ? e.message : String(e);
31+
log.warn(`Research generation failed for ${protocol.name}:`, message);
1732
return null;
1833
});
1934

20-
const report = await runLoreAgent(protocol, metrics);
2135
if (report) {
2236
saveReport(report);
2337
printReport(report);
2438
}
39+
40+
return report;
2541
}
2642

2743
async function researchAll(): Promise<void> {
44+
const startedAt = Date.now();
2845
const protocols = getAllProtocols().slice(0, config.MAX_PROTOCOLS_PER_RUN);
2946
log.info(`Researching ${protocols.length} protocols...`);
47+
const cycleReports: ResearchReport[] = [];
48+
let skippedProtocols = 0;
3049

3150
for (const protocol of protocols) {
32-
await researchProtocol(protocol.id);
33-
// small delay to avoid rate limits
34-
await new Promise((r) => setTimeout(r, 1000));
51+
const report = await researchProtocol(protocol.id);
52+
if (report) {
53+
cycleReports.push(report);
54+
} else {
55+
skippedProtocols++;
56+
}
57+
58+
await sleep(1000);
3559
}
3660

3761
const all = getAllReports();
38-
log.info(`Research complete. ${all.length} reports generated.`);
39-
log.info(`Top protocol: ${all[0]?.protocolName} (${all[0]?.overallScore}) — ${all[0]?.verdict}`);
62+
const leader = cycleReports.sort((a, b) => b.overallScore - a.overallScore)[0];
63+
const durationMs = Date.now() - startedAt;
64+
65+
log.info(
66+
`Research complete. ${cycleReports.length} reports generated this cycle | ${skippedProtocols} skipped | ${all.length} stored total`,
67+
);
68+
69+
if (leader) {
70+
log.info(`Top protocol this cycle: ${leader.protocolName} (${leader.overallScore}) - ${leader.verdict}`);
71+
} else {
72+
log.info("No protocol reports qualified this cycle");
73+
}
74+
75+
log.info("Lore research cycle complete", { durationMs });
4076
}
4177

4278
async function main(): Promise<void> {
43-
log.info("Lore v0.1.0 DeFi protocol research agent");
79+
log.info("Lore v0.1.0 - DeFi protocol research agent");
4480

4581
const target = process.argv[2];
4682
if (target) {
4783
await researchProtocol(target);
4884
} else {
49-
await researchAll();
50-
setInterval(() => researchAll().catch((e) => log.error("Research cycle error:", e)), config.REFRESH_INTERVAL_MS);
85+
let cycleInFlight = false;
86+
let skippedCycles = 0;
87+
88+
const tick = async () => {
89+
if (cycleInFlight) {
90+
skippedCycles++;
91+
log.warn("Skipping research cycle because the previous sweep is still running", {
92+
skippedCycles,
93+
});
94+
return;
95+
}
96+
97+
cycleInFlight = true;
98+
try {
99+
await researchAll();
100+
} catch (e) {
101+
log.error("Research cycle error:", e);
102+
} finally {
103+
cycleInFlight = false;
104+
}
105+
};
106+
107+
await tick();
108+
setInterval(() => {
109+
void tick();
110+
}, config.REFRESH_INTERVAL_MS);
51111
}
52112
}
53113

54-
main().catch((e) => { log.error("Fatal:", e); process.exit(1); });
114+
main().catch((e) => {
115+
log.error("Fatal:", e);
116+
process.exit(1);
117+
});

0 commit comments

Comments
 (0)