mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
116 lines
3.6 KiB
JavaScript
116 lines
3.6 KiB
JavaScript
"use strict";
|
|
|
|
const GPT_MODELS = ["gpt-4o-mini", "chatgpt-4o-latest", "gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"];
|
|
const SYSTEM_MESSAGE = "I'm working on my fantasy map.";
|
|
|
|
function geneateWithAi(defaultPrompt, onApply) {
|
|
updateValues();
|
|
|
|
$("#aiGenerator").dialog({
|
|
title: "AI Text Generator",
|
|
position: {my: "center", at: "center", of: "svg"},
|
|
resizable: false,
|
|
buttons: {
|
|
Generate: function (e) {
|
|
generate(e.target);
|
|
},
|
|
Apply: function () {
|
|
const result = byId("aiGeneratorResult").value;
|
|
if (!result) return tip("No result to apply", true, "error", 4000);
|
|
onApply(result);
|
|
$(this).dialog("close");
|
|
},
|
|
Close: function () {
|
|
$(this).dialog("close");
|
|
}
|
|
}
|
|
});
|
|
|
|
if (modules.geneateWithAi) return;
|
|
modules.geneateWithAi = true;
|
|
|
|
function updateValues() {
|
|
byId("aiGeneratorResult").value = "";
|
|
byId("aiGeneratorPrompt").value = defaultPrompt;
|
|
byId("aiGeneratorKey").value = localStorage.getItem("fmg-ai-kl") || "";
|
|
|
|
const select = byId("aiGeneratorModel");
|
|
select.options.length = 0;
|
|
GPT_MODELS.forEach(model => select.options.add(new Option(model, model)));
|
|
select.value = localStorage.getItem("fmg-ai-model") || GPT_MODELS[0];
|
|
}
|
|
|
|
async function generate(button) {
|
|
const key = byId("aiGeneratorKey").value;
|
|
if (!key) return tip("Please enter an OpenAI API key", true, "error", 4000);
|
|
localStorage.setItem("fmg-ai-kl", key);
|
|
|
|
const model = byId("aiGeneratorModel").value;
|
|
if (!model) return tip("Please select a model", true, "error", 4000);
|
|
localStorage.setItem("fmg-ai-model", model);
|
|
|
|
const prompt = byId("aiGeneratorPrompt").value;
|
|
if (!prompt) return tip("Please enter a prompt", true, "error", 4000);
|
|
|
|
try {
|
|
button.disabled = true;
|
|
const resultArea = byId("aiGeneratorResult");
|
|
resultArea.value = "";
|
|
resultArea.disabled = true;
|
|
|
|
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${key}`
|
|
},
|
|
body: JSON.stringify({
|
|
model,
|
|
messages: [
|
|
{role: "system", content: SYSTEM_MESSAGE},
|
|
{role: "user", content: prompt}
|
|
],
|
|
temperature: 1.2,
|
|
stream: true // Enable streaming
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const json = await response.json();
|
|
throw new Error(json?.error?.message || "Failed to generate");
|
|
}
|
|
|
|
const reader = response.body.getReader();
|
|
const decoder = new TextDecoder("utf-8");
|
|
let buffer = "";
|
|
|
|
while (true) {
|
|
const {done, value} = await reader.read();
|
|
if (done) break;
|
|
|
|
buffer += decoder.decode(value, {stream: true});
|
|
const lines = buffer.split("\n");
|
|
|
|
for (let i = 0; i < lines.length - 1; i++) {
|
|
const line = lines[i].trim();
|
|
if (line.startsWith("data: ") && line !== "data: [DONE]") {
|
|
try {
|
|
const jsonData = JSON.parse(line.slice(6));
|
|
const content = jsonData.choices[0].delta.content;
|
|
if (content) resultArea.value += content;
|
|
} catch (jsonError) {
|
|
console.warn("Failed to parse JSON:", jsonError, "Line:", line);
|
|
}
|
|
}
|
|
}
|
|
|
|
buffer = lines[lines.length - 1];
|
|
}
|
|
} catch (error) {
|
|
return tip(error.message, true, "error", 4000);
|
|
} finally {
|
|
button.disabled = false;
|
|
byId("aiGeneratorResult").disabled = false;
|
|
}
|
|
}
|
|
}
|