#!/usr/bin/env node import { createServer } from 'node:http'; function readPort(argv) { if (argv.length !== 2 || argv[0] !== '--port' || !/^\d+$/.test(argv[1])) { throw new Error('Usage: node generation-node-smoke-server.mjs --port '); } const port = Number(argv[1]); if (port < 1 || port > 65_535) throw new Error(`Invalid port: ${argv[1]}`); return port; } const port = readPort(process.argv.slice(2)); const outlinePayload = JSON.stringify({ languageDirective: 'Teach in English with concise explanations.', courseTitle: 'Node Smoke Course', outlines: [ { id: 'scene_1', type: 'slide', title: 'Smoke-Test Outline', description: 'Confirms outline generation through an OpenAI-compatible endpoint.', keyPoints: ['Package import', 'HTTP model seam', 'Outline validation'], order: 1, }, ], }); const slideContentPayload = JSON.stringify({ elements: [ { type: 'text', left: 80, top: 80, width: 840, height: 100, content: 'Dependency injection keeps model routing outside the generation package.', }, ], background: { type: 'solid', color: '#ffffff' }, remark: 'A deterministic slide generated by the bare-Node consumer smoke.', }); const slideActionsPayload = JSON.stringify([ { type: 'text', content: 'Dependency injection lets the caller control the model while generation stays pure.', }, ]); const server = createServer((request, response) => { if (request.method === 'GET' && request.url === '/health') { response.writeHead(200, { 'content-type': 'text/plain' }); response.end('ok'); return; } if (request.method !== 'POST' || request.url !== '/chat/completions') { response.writeHead(404, { 'content-type': 'application/json' }); response.end(JSON.stringify({ error: 'not found' })); return; } let body = ''; request.setEncoding('utf8'); request.on('data', (chunk) => { body += chunk; }); request.on('end', () => { try { const payload = JSON.parse(body); if (!payload.model || !Array.isArray(payload.messages)) { throw new Error('model and messages are required'); } const system = payload.messages.find((message) => message.role === 'system')?.content; const content = typeof system === 'string' && system.startsWith('# Slide Content Generator') ? slideContentPayload : typeof system === 'string' && system.startsWith('# Slide Action Generator') ? slideActionsPayload : outlinePayload; response.writeHead(200, { 'content-type': 'application/json' }); response.end( JSON.stringify({ id: 'chatcmpl-generation-smoke', object: 'chat.completion', choices: [{ index: 0, message: { role: 'assistant', content } }], }), ); } catch (error) { response.writeHead(400, { 'content-type': 'application/json' }); response.end(JSON.stringify({ error: String(error) })); } }); }); server.listen(port, '127.0.0.1', () => { console.log(`Generation smoke server listening on http://127.0.0.1:${port}`); }); const close = () => server.close(() => process.exit(0)); process.on('SIGINT', close); process.on('SIGTERM', close);