diff --git a/src/agents/tools/utils/dsn/dsnDownload.ts b/src/agents/tools/utils/dsn/dsnDownload.ts index 72c7b438..2ca23ea9 100644 --- a/src/agents/tools/utils/dsn/dsnDownload.ts +++ b/src/agents/tools/utils/dsn/dsnDownload.ts @@ -12,7 +12,7 @@ interface BaseMemory { [key: string]: unknown; } -export async function download(cid: string): Promise { +export const download = async (cid: string): Promise => { return withRetry( async () => { const api = createAutoDriveApi({ @@ -47,4 +47,4 @@ export async function download(cid: string): Promise { }, }, ); -} +}; diff --git a/src/agents/tools/utils/dsn/retry.ts b/src/agents/tools/utils/dsn/retry.ts index 545c1400..191fd481 100644 --- a/src/agents/tools/utils/dsn/retry.ts +++ b/src/agents/tools/utils/dsn/retry.ts @@ -2,7 +2,7 @@ import { createLogger } from '../../../../utils/logger.js'; const logger = createLogger('retry-utility'); -export async function withRetry( +export const withRetry = async ( operation: () => Promise, { maxRetries = 5, @@ -10,7 +10,7 @@ export async function withRetry( operationName = 'Operation', shouldRetry = (_error: unknown): boolean => true, } = {}, -): Promise { +): Promise => { const attempt = async (retriesLeft: number, currentDelay: number): Promise => { try { return await operation(); @@ -33,4 +33,4 @@ export async function withRetry( }; return attempt(maxRetries, initialDelayMs); -} +}; diff --git a/src/cli/resurrect.ts b/src/cli/resurrect.ts index 29500fb6..d6242cea 100644 --- a/src/cli/resurrect.ts +++ b/src/cli/resurrect.ts @@ -1,18 +1,17 @@ import { join } from 'path'; import { mkdirSync } from 'fs'; import { createLogger } from '../utils/logger.js'; -import MemoryResurrector from '../utils/resurrection.js'; +import { downloadAllMemories } from '../utils/resurrection.js'; const logger = createLogger('resurrect-cli'); -async function main() { +const main = async () => { try { const outputDir = join(process.cwd(), 'memories'); mkdirSync(outputDir, { recursive: true }); logger.info('Starting memory resurrection...'); - const resurrector = new MemoryResurrector(outputDir); - const result = await resurrector.downloadAllMemories(); + const result = await downloadAllMemories(outputDir); logger.info( `Memory resurrection complete. Processed: ${result.processed}, Failed: ${result.failed}`, @@ -22,6 +21,6 @@ async function main() { logger.error('Failed to resurrect memories:', error); process.exit(1); } -} +}; main(); diff --git a/src/utils/resurrection.ts b/src/utils/resurrection.ts index b8be1702..1ed2fef6 100644 --- a/src/utils/resurrection.ts +++ b/src/utils/resurrection.ts @@ -7,83 +7,95 @@ import { join } from 'path'; const logger = createLogger('memory-resurrector'); const STATE_FILE = join(process.cwd(), 'memories', 'last-processed-cid.json'); -class MemoryResurrector { - private failedCids: Set = new Set(); - private processedCount: number = 0; - - constructor(private outputDir: string) {} - - private getLastProcessedCid(): string | null { - try { - if (!existsSync(STATE_FILE)) { - return null; - } - const data = JSON.parse(readFileSync(STATE_FILE, 'utf-8')); - return data.lastProcessedCid; - } catch (error) { - logger.error('Failed to read last processed CID:', error); +const getLastProcessedCid = (): string | null => { + try { + if (!existsSync(STATE_FILE)) { return null; } + const data = JSON.parse(readFileSync(STATE_FILE, 'utf-8')); + return data.lastProcessedCid; + } catch (error) { + logger.error('Failed to read last processed CID:', error); + return null; } - - private saveLastProcessedCid(cid: string): void { - try { - writeFileSync(STATE_FILE, JSON.stringify({ lastProcessedCid: cid }, null, 2)); - logger.info(`Saved last processed CID: ${cid}`); - } catch (error) { - logger.error('Failed to save last processed CID:', error); - } +}; + +const saveLastProcessedCid = (cid: string): void => { + try { + writeFileSync(STATE_FILE, JSON.stringify({ lastProcessedCid: cid }, null, 2)); + logger.info(`Saved last processed CID: ${cid}`); + } catch (error) { + logger.error('Failed to save last processed CID:', error); + } +}; + +const fetchMemoryChain = async ( + currentCid: string, + stopAtCid: string | null, + outputDir: string, + failedCids: Set = new Set(), + processedCount = 0, +): Promise<{ processedCount: number; failedCids: Set }> => { + if (!currentCid || failedCids.has(currentCid) || currentCid === stopAtCid) { + return { processedCount, failedCids }; } - private async fetchMemoryChain(currentCid: string, stopAtCid: string | null): Promise { - if (!currentCid || this.failedCids.has(currentCid) || currentCid === stopAtCid) { - return; + try { + const content = await download(currentCid); + const filename = `${currentCid}.json`; + const filepath = join(outputDir, filename); + writeFileSync(filepath, JSON.stringify(content, null, 2)); + + processedCount++; + logger.info(`Successfully fetched and saved memory ${currentCid}`); + + if (content.previousCid && content.previousCid !== stopAtCid) { + return fetchMemoryChain( + content.previousCid, + stopAtCid, + outputDir, + failedCids, + processedCount, + ); } + } catch (error) { + logger.error(`Failed to fetch memory ${currentCid}:`, error); + failedCids.add(currentCid); + } - try { - const content = await download(currentCid); - - const filename = `${currentCid}.json`; - const filepath = join(this.outputDir, filename); - writeFileSync(filepath, JSON.stringify(content, null, 2)); - - this.processedCount++; - logger.info(`Successfully fetched and saved memory ${currentCid}`); + return { processedCount, failedCids }; +}; - if (content.previousCid && content.previousCid !== stopAtCid) { - await this.fetchMemoryChain(content.previousCid, stopAtCid); - } - } catch (error) { - logger.error(`Failed to fetch memory ${currentCid}:`, error); - this.failedCids.add(currentCid); - } +const downloadAllMemories = async ( + outputDir: string, +): Promise<{ processed: number; failed: number }> => { + const latestCid = await getLastMemoryCid(); + if (!latestCid) { + logger.info('No memories found (empty CID)'); + return { processed: 0, failed: 0 }; } - async downloadAllMemories(): Promise<{ processed: number; failed: number }> { - const latestCid = await getLastMemoryCid(); - if (!latestCid) { - logger.info('No memories found (empty CID)'); - return { processed: 0, failed: 0 }; - } - - const lastProcessedCid = this.getLastProcessedCid(); - if (lastProcessedCid === latestCid) { - logger.info('Already up to date with latest CID'); - return { processed: 0, failed: 0 }; - } + const lastProcessedCid = getLastProcessedCid(); + if (lastProcessedCid === latestCid) { + logger.info('Already up to date with latest CID'); + return { processed: 0, failed: 0 }; + } - logger.info(`Starting download from ${latestCid} to ${lastProcessedCid || 'genesis'}`); - await this.fetchMemoryChain(latestCid, lastProcessedCid); + logger.info(`Starting download from ${latestCid} to ${lastProcessedCid || 'genesis'}`); + const { processedCount, failedCids } = await fetchMemoryChain( + latestCid, + lastProcessedCid, + outputDir, + ); - this.saveLastProcessedCid(latestCid); + saveLastProcessedCid(latestCid); - logger.info(`Downloaded ${this.processedCount} memories, failed CIDs: ${this.failedCids.size}`); + logger.info(`Downloaded ${processedCount} memories, failed CIDs: ${failedCids.size}`); - return { - processed: this.processedCount, - failed: this.failedCids.size, - }; - } -} + return { + processed: processedCount, + failed: failedCids.size, + }; +}; -export default MemoryResurrector; +export { downloadAllMemories };