Files
openmaic/OpenMAIC/scripts/generation-node-smoke-server.mjs
2026-08-16 14:58:47 +08:00

104 lines
3.2 KiB
JavaScript

#!/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 <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);