// ============================================================================ // Step 00a: Site Audit (DataForSEO + AI) // ============================================================================ import { PageAuditor } from "@mintel/page-audit"; import type { ConceptState, StepResult, PipelineConfig } from "../types.js"; export async function executeSiteAudit( state: ConceptState, config: PipelineConfig, ): Promise { const startTime = Date.now(); if (!state.url) { return { success: true, data: null, usage: { step: "00a-site-audit", model: "none", promptTokens: 0, completionTokens: 0, cost: 0, durationMs: Date.now() - startTime }, }; } try { const login = process.env.DATA_FOR_SEO_LOGIN || process.env.DATA_FOR_SEO_API_KEY?.split(":")?.[0]; const password = process.env.DATA_FOR_SEO_PASSWORD || process.env.DATA_FOR_SEO_API_KEY?.split(":")?.slice(1)?.join(":"); if (!login || !password) { console.warn(" ⚠️ Site Audit skipped: DataForSEO credentials missing from environment."); return { success: true, data: null, usage: { step: "00a-site-audit", model: "none", promptTokens: 0, completionTokens: 0, cost: 0, durationMs: Date.now() - startTime }, }; } const auditor = new PageAuditor({ dataForSeoLogin: login, dataForSeoPassword: password, openrouterKey: config.openrouterKey, outputDir: config.outputDir ? `${config.outputDir}/audits` : undefined, }); // Run audit (max 20 pages for the estimation phase to keep it fast) const result = await auditor.audit(state.url, { maxPages: 20 }); return { success: true, data: result, usage: { step: "00a-site-audit", model: "dataforseo", cost: 0, // DataForSEO cost tracking could be added later promptTokens: 0, completionTokens: 0, durationMs: Date.now() - startTime, }, }; } catch (err: any) { console.warn(` ⚠️ Site Audit failed, skipping: ${err.message}`); return { success: true, data: null, usage: { step: "00a-site-audit", model: "none", promptTokens: 0, completionTokens: 0, cost: 0, durationMs: Date.now() - startTime }, }; } }