oc.thread.on("MessageAdded", async function () {
let lastMessage = oc.thread.messages.at(-1);
// console.log(lastMessage);
if (lastMessage.author !== "ai") {
if (oc.character.customData.description != "") return
oc.thread.messages.push({
author: "user",
content: `${oc.character.name}, describe your current appearance in detail. Reply with a comma-separated list of keywords and keyphrases which *visually* capture your apprearance only. Imagine you're giving a list of keywords to an artist who will use them to draw you. Describe the your appearance with keywords/keyphrases, including your race, class, age, etc. Respond with only the comma-separated keyphrases - nothing more, nothing less.
Start with "Here is my current appearance:"`,
});
}
});
window.alreadyGenerating = false;
oc.thread.on("MessageAdded", async function () {
oc.character.customData.description = oc.character.customData.description
? oc.character.customData.description
: "";
let lastMessage = oc.thread.messages.at(-1);
if (alreadyGenerating) return;
alreadyGenerating = true;
if (lastMessage.author === "ai") {
console.log("DESC: ", oc.character.customData.description);
if (/^Here is my current appearance\:/.test(lastMessage.content)) {
if (oc.character.customData.description == "") {
oc.character.customData.description = lastMessage.content.replace(
"Here is my current appearance:",
""
);
// console.log("NEW DESC: ", oc.character.customData.description);
oc.character.customData.PUBLIC = {
description: oc.character.customData.description,
};
// console.log("PUBLIC: ", oc.character.customData.PUBLIC);
}
oc.thread.messages.pop();
oc.thread.messages.pop();
} else {
// oc.thread.messages.pop()
let response = await oc.getInstructCompletion({
instruction: `Given the message below, infer the emotions that can be sensed on the message:
---
${lastMessage.content}
---
Be sure to only give the words that describes the emotion e.g. joy, sad, happy, cheeky, etc.
Do not reply with a sentence, only keywords of the emotion.`,
stopSequences: ["\n\n"],
});
let prompt = `${oc.character.customData.description}, (in ${response.text} expression:1.1), portrait, digital art, detailed, concept portrait art, uhd, 8k`;
(async function () {
// let prevDataUrl = oc.character.avatar.url;
let { dataUrl } = await oc.textToImage({
prompt: prompt,
negativePrompt: `(semi-realistic, hands, worst quality, blurry, low resolution, low quality:1.2)`,
seed: `104`,
resolution: `512x768`,
});
oc.thread.messages.push({
author: "ai",
content: `<br><img src="${await resizeDataURLWidth(
dataUrl,
200
)}" title="${prompt}">`,
hiddenFrom: ["ai"],
});
})();
}
}
alreadyGenerating = false;
});
async function resizeDataURLWidth(dataURL, newWidth) {
const blob = await fetch(dataURL).then((res) => res.blob());
const bitmap = await createImageBitmap(blob);
const canvas = Object.assign(document.createElement("canvas"), {
width: newWidth,
height: (bitmap.height / bitmap.width) * newWidth,
});
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL("image/jpeg");
}