File size: 4,309 Bytes
d10a0b0 33115b6 e9cac85 d10a0b0 1a7bc8e 956ccbc d10a0b0 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd 33115b6 68ceccd d10a0b0 33115b6 956ccbc 33115b6 956ccbc 33115b6 956ccbc 33115b6 956ccbc 33115b6 956ccbc 80b5887 956ccbc 33115b6 80b5887 956ccbc d10a0b0 956ccbc 33115b6 956ccbc 33115b6 956ccbc e9cac85 956ccbc 33115b6 956ccbc |
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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
const express = require('express');
const bodyParser = require('body-parser');
const { exec } = require('child_process');
// Ensure fetch is available in Node.js
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
const app = express();
const port = 7860;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", (req, res) => {
res.set('Content-Type', 'text/plain');
res.send(`βοΈ Sunny API Server
> You're using this server to test or eval code with Sunny!
Supported models:
- sunny: Run Node.js code
- sunny-shell: Run real shell commands
- sunny-plus: Get long-form code explanations via text.pollinations.ai
π Educational use only.
`);
});
// Models endpoint
app.get("/models", (req, res) => {
res.json({
object: "list",
data: [
{
id: "sunny",
object: "model",
owned_by: "sunny-dev",
created: Date.now()
},
{
id: "sunny-shell",
object: "model",
owned_by: "sunny-dev",
created: Date.now()
},
{
id: "sunny-plus",
object: "model",
owned_by: "sunny-dev",
created: Date.now()
}
]
});
});
// Chat/completions endpoint
app.post("/chat/completions", async (req, res) => {
const model = req.body.model || "sunny";
const messages = req.body.messages || [];
const outputs = [];
const logs = [];
let totalPromptTokens = 0;
for (const msg of messages) {
const inputCode = msg.content || "";
const promptTokens = inputCode.split(/\s+/).length;
totalPromptTokens += promptTokens;
try {
if (model === "sunny-shell") {
// Shell execution
const result = await new Promise((resolve) => {
exec(inputCode, { timeout: 10000 }, (err, stdout, stderr) => {
if (err) return resolve(`Shell Error: ${stderr || err.message}`);
resolve(stdout || "No output from shell.");
});
});
outputs.push(result.trim());
logs.push("Executed Shell: " + inputCode);
}
else if (model === "sunny-plus") {
// Pollinations AI explanation
const pollinationURL = `https://text.pollinations.ai/${encodeURIComponent("Explain this code: " + inputCode)}`;
const response = await fetch(pollinationURL);
const explanation = await response.text();
outputs.push(explanation.trim());
logs.push("Fetched explanation via Pollinations.");
}
else {
// Default NodeJS eval
const consoleCapture = [];
const customConsole = {
log: (...args) => consoleCapture.push(args.join(" ")),
error: (...args) => consoleCapture.push("ERROR: " + args.join(" "))
};
const wrappedCode = `
(async () => {
let result;
try {
const console = customConsole;
result = await (async () => { ${inputCode} })();
if (result !== undefined) console.log(result);
} catch (e) {
console.error("Runtime Error:", e.message);
}
})();
`;
eval(wrappedCode);
outputs.push(consoleCapture.join("\n") || "Execution Finished.");
logs.push("NodeJS evaluated.");
}
} catch (err) {
outputs.push("Execution Error: " + err.message);
logs.push("Caught Error: " + err.message);
}
}
const outputText = outputs.join("\n\n");
const completionTokens = outputText.split(/\s+/).length;
res.json({
id: "chatcmpl-" + Math.random().toString(36).substring(2, 10),
object: "chat.completion",
created: Math.floor(Date.now() / 1000),
model,
choices: [
{
index: 0,
message: {
role: "assistant",
content: outputText
},
finish_reason: "stop"
}
],
usage: {
prompt_tokens: totalPromptTokens,
completion_tokens: completionTokens,
total_tokens: totalPromptTokens + completionTokens
},
logs
});
});
// End of service when the user is tired or pauses
app.post("/end-of-service", (req, res) => {
res.send("End of service. Rest well!");
});
app.listen(port, () => {
console.log(`Sunny server running on port ${port}`);
});
|