File size: 2,059 Bytes
dd480ef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | /**
* Simulator Simulate Route — UPGRADED
* Provider-agnostic dry-run simulation using LLM Gateway
*/
import { Router } from 'express';
import { z } from 'zod';
import { logger } from '../index';
import { DryRunSimulator } from '../agents/simulator';
import { createRequestLLM } from '../services/llmClient';
import type { N8nWorkflow, WorkflowGraph, WorkflowArchitecturePlan } from '../types/workflow';
export const simulateRoute: Router = Router();
const SimulateSchema = z.object({
jobId: z.string(),
workflow: z.record(z.unknown()),
graph: z.record(z.unknown()),
architecturePlan: z.record(z.unknown()).optional(),
mockData: z.record(z.unknown()).optional(),
llmApiKey: z.string().optional(),
openaiApiKey: z.string().optional(),
llmModel: z.string().optional(),
});
simulateRoute.post('/', async (req, res) => {
const parsed = SimulateSchema.safeParse(req.body);
if (!parsed.success) {
res.status(400).json({ success: false, error: 'Invalid request', details: parsed.error.flatten() });
return;
}
const { jobId, workflow, graph, architecturePlan } = parsed.data;
const apiKey = parsed.data.llmApiKey ?? parsed.data.openaiApiKey ?? process.env['LLM_API_KEY'] ?? process.env['OPENAI_API_KEY'] ?? '';
logger.info({ jobId }, '[Simulate] Starting dry-run simulation');
try {
const llm = createRequestLLM(apiKey);
const simulator = new DryRunSimulator(llm);
const simulationReport = await simulator.simulate(
jobId,
workflow as any as N8nWorkflow,
graph as any as WorkflowGraph,
(architecturePlan ?? {}) as any as WorkflowArchitecturePlan,
);
logger.info({
jobId,
passed: simulationReport.passed,
score: simulationReport.readinessScore,
}, '[Simulate] Complete');
res.json({ success: true, simulationReport });
} catch (err) {
const message = err instanceof Error ? err.message : 'Simulation error';
logger.error({ jobId, err }, '[Simulate] Failed');
res.status(500).json({ success: false, error: message, jobId });
}
});
|