diff --git a/no-reply-api/package.json b/no-reply-api/package.json new file mode 100644 index 0000000..0798fd9 --- /dev/null +++ b/no-reply-api/package.json @@ -0,0 +1,9 @@ +{ + "name": "whispergate-no-reply-api", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "start": "node server.mjs" + } +} diff --git a/no-reply-api/server.mjs b/no-reply-api/server.mjs new file mode 100644 index 0000000..4e999fc --- /dev/null +++ b/no-reply-api/server.mjs @@ -0,0 +1,82 @@ +import http from "node:http"; + +const port = Number(process.env.PORT || 8787); +const modelName = process.env.NO_REPLY_MODEL || "whispergate-no-reply-v1"; + +function sendJson(res, status, payload) { + res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" }); + res.end(JSON.stringify(payload)); +} + +function noReplyChatCompletion(reqBody) { + return { + id: `chatcmpl_whispergate_${Date.now()}`, + object: "chat.completion", + created: Math.floor(Date.now() / 1000), + model: reqBody?.model || modelName, + choices: [ + { + index: 0, + message: { role: "assistant", content: "NO_REPLY" }, + finish_reason: "stop" + } + ], + usage: { prompt_tokens: 0, completion_tokens: 1, total_tokens: 1 } + }; +} + +function noReplyResponses(reqBody) { + return { + id: `resp_whispergate_${Date.now()}`, + object: "response", + created_at: Math.floor(Date.now() / 1000), + model: reqBody?.model || modelName, + output: [ + { + type: "message", + role: "assistant", + content: [{ type: "output_text", text: "NO_REPLY" }] + } + ], + usage: { input_tokens: 0, output_tokens: 1, total_tokens: 1 } + }; +} + +const server = http.createServer((req, res) => { + if (req.method === "GET" && req.url === "/health") { + return sendJson(res, 200, { ok: true, service: "whispergate-no-reply-api" }); + } + + if (req.method !== "POST") { + return sendJson(res, 404, { error: "not_found" }); + } + + let body = ""; + req.on("data", (chunk) => { + body += chunk; + if (body.length > 1_000_000) req.destroy(); + }); + + req.on("end", () => { + let parsed = {}; + try { + parsed = body ? JSON.parse(body) : {}; + } catch { + return sendJson(res, 400, { error: "invalid_json" }); + } + + if (req.url === "/v1/chat/completions") { + return sendJson(res, 200, noReplyChatCompletion(parsed)); + } + + if (req.url === "/v1/responses") { + return sendJson(res, 200, noReplyResponses(parsed)); + } + + return sendJson(res, 404, { error: "not_found" }); + }); +}); + +server.listen(port, () => { + console.log(`[whispergate-no-reply-api] listening on :${port}`); +});