ventures: refresh havre from havre-next
This commit is contained in:
1 parent
b1328774a3
commit
d0c700e2ab
4 files changed
+40
-23
No files matched your search
@@ -89,10 +89,11 @@ export const hearingPerMinute = (model) => (model && model.perSecond != null ? m
|
||||
const SAFE = "Keep it safe for work: no nudity, nothing sexual, no gore. Everyone shown is an adult. Never show a real, " +
|
||||
"identifiable person: no celebrities, no public figures, no one the conversation says is real; if one is asked for, show " +
|
||||
"the character alone. No words, logos or watermarks in the picture.";
|
||||
// for an adult character's photos and clips (adultCheck): the same rules, less the one about work, and a hard one first.
|
||||
// It says who is shown, not who isn't: the words for that are the ones filters look for (and Havre's own check, underage)
|
||||
export const ADULT_ONLY = "Hard rule, 18+ only: everyone shown is an adult, 18 or older, with a grown adult face and body.";
|
||||
const ADULT = ADULT_ONLY + " If the conversation asks for anyone younger, or for anything that makes someone look younger, " +
|
||||
// for an adult character's photos and clips (adultCheck): the same rules, less the one about work, and a hard one first,
|
||||
// as the shot writer (a text model) reads it: it can be told the number. It says who is shown, not who isn't: the words
|
||||
// for that are the ones filters look for (and Havre's own check, underage)
|
||||
export const EIGHTEEN = "Hard rule, 18+ only: everyone shown is an adult, 18 or older, with a grown adult face and body.";
|
||||
const ADULT = EIGHTEEN + " If the conversation asks for anyone younger, or for anything that makes someone look younger, " +
|
||||
"leave it out and show only adults. Never show a real, identifiable person: no celebrities, no public figures, no one the " +
|
||||
"conversation says is real; if one is asked for, show the character alone. No gore. No words, logos or watermarks in the " +
|
||||
"picture.";
|
||||
@@ -164,8 +165,13 @@ export function cleanText(text, max = 900) {
|
||||
// the rules ride at the front of every picture and clip, where a long shot or a long look can't push them out. They
|
||||
// say what's wanted: an image model reads the words, not the "no" in front of them, and so does a content filter
|
||||
const KEEP = "Safe for work: everyone in it is an adult, fully clothed.";
|
||||
// an adult character's: the 18+ rule is the very first thing the model reads
|
||||
const KEEP_ADULT = ADULT_ONLY + " Never a real, identifiable person.";
|
||||
// an adult character's: the 18+ rule is the very first thing the picture model reads, in words a content filter
|
||||
// doesn't take for an age or for anyone it guards. The number, "body", "hard rule" and "identifiable person" stay
|
||||
// with the shot writer (EIGHTEEN, ADULT), whose instructions never reach a picture filter: a picture prompt with safe
|
||||
// mode off is read the hardest, and a from-scratch adult character's photo was turned down on every model, with the
|
||||
// plainest shot and look, while the same words went out before every one of them.
|
||||
export const ADULT_ONLY = "Everyone shown is a grown adult.";
|
||||
const KEEP_ADULT = ADULT_ONLY;
|
||||
|
||||
/** how their card says they look, on one line, without a full stop at the end ("" when it doesn't say) */
|
||||
const lookWords = (card) => str(card && card.look && card.look.description, 4000).replace(/\s+/g, " ").trim().replace(/[.!?…]+$/, "");
|
||||
|
||||
@@ -164,9 +164,13 @@ it didn't come.
|
||||
|
||||
The one exception is an `adult` character, once the person has said they're 18 or older: when every picture on their
|
||||
card was made with AI (never one that was uploaded, which could be of anyone), their photos and clips can be adult.
|
||||
`A.adultCheck(card, { of18, made, shot, said })` decides; they go to Venice's uncensored models with safe mode off,
|
||||
and every prompt opens with the 18+ rule (`A.ADULT_ONLY`). Never when the card, the shot or the chat mentions anyone
|
||||
under 18 (`A.underage`): then it's safe for work, as usual. The pictures made for their card go without safe mode
|
||||
`A.adultCheck(card, { of18, made, shot, said })` decides; they go to Venice's uncensored models with safe mode off.
|
||||
The shot is written to the 18+ rule with the number in it (`A.EIGHTEEN`, in the shot writer's instructions, which
|
||||
no picture filter reads), and every picture and clip prompt opens with the same rule in words a filter doesn't take
|
||||
for an age or for anyone it guards (`A.ADULT_ONLY`, "Everyone shown is a grown adult."): a picture prompt sent with
|
||||
safe mode off is read the hardest, and "18+", "body", "hard rule" or "identifiable person" in it got the plainest
|
||||
photo turned down on every model. Never when the card, the shot or the chat mentions anyone under 18
|
||||
(`A.underage`): then it's safe for work, as usual. The pictures made for their card go without safe mode
|
||||
too: a portrait drawn from words (`A.portraitPrompt(card, limit, { adult: true })`, when
|
||||
`A.adultCheck(card, { of18, drawn: true })` says so), and one made from their pictures when every one of those was
|
||||
made with AI.
|
||||
|
||||
@@ -131,7 +131,7 @@ test("pictures made from their pictures keep their face and follow how their car
|
||||
const drawn = A.portraitPrompt(long);
|
||||
assert.ok(drawn.length <= 1500);
|
||||
assert.match(drawn, /… Safe for work: everyone in it is an adult, fully clothed\. Head and shoulders, soft light, plain background, no text\.$/);
|
||||
assert.match(A.portraitPrompt(long, 1500, { adult: true }), /^Hard rule.*Portrait photo of Ines Corbel.*… Head and shoulders, soft light, plain background, no text\.$/);
|
||||
assert.match(A.portraitPrompt(long, 1500, { adult: true }), /^Everyone shown is a grown adult\. Portrait photo of Ines Corbel.*… Head and shoulders, soft light, plain background, no text\.$/);
|
||||
assert.match(A.portraitPrompt({ ...bare, tagline: "Ferry pilot." }), /an original adult character: Ferry pilot\. Safe for work/);
|
||||
assert.match(A.portraitPrompt({ ...bare, tagline: "" }), /an original adult character: an original character\. Safe for work/);
|
||||
});
|
||||
@@ -141,12 +141,15 @@ const mara = C.normalizeCard({ name: "Mara Vell", persona: "You are Mara Vell, a
|
||||
portrait: "data:image/webp;base64,AAAA", look: { references: ["data:image/webp;base64,BBBB"] } });
|
||||
|
||||
test("adult characters: the 18+ rule is the first thing every photo and clip prompt says, and the shot's", () => {
|
||||
assert.equal(A.ADULT_ONLY, "Hard rule, 18+ only: everyone shown is an adult, 18 or older, with a grown adult face and body.");
|
||||
// the shot writer, a text model, is told the number; the picture model reads the same rule in words no filter takes
|
||||
// for an age (or for anyone it guards): a picture prompt with safe mode off is read the hardest
|
||||
assert.equal(A.EIGHTEEN, "Hard rule, 18+ only: everyone shown is an adult, 18 or older, with a grown adult face and body.");
|
||||
assert.equal(A.ADULT_ONLY, "Everyone shown is a grown adult.");
|
||||
for (const p of [A.photoPrompt(mara, "On the stage.", 1, 1500, { adult: true }), A.photoPrompt(mara, "On the stage.", 2, 1500, { adult: true }),
|
||||
A.clipPrompt(mara, "She bows.", 2500, { adult: true })]) {
|
||||
assert.ok(p.startsWith(A.ADULT_ONLY), p);
|
||||
assert.ok(p.startsWith(A.ADULT_ONLY + " The reference picture"), p);
|
||||
assert.ok(!/Safe for work/.test(p));
|
||||
assert.match(p, /Never a real, identifiable person\./);
|
||||
assert.ok(!/\d|identifiable|hard rule|body/i.test(p), "no age, no one it guards, nothing for a filter to read: " + p);
|
||||
}
|
||||
assert.ok(A.photoPrompt(mara, "x ".repeat(3000), 1, 400, { adult: true }).startsWith(A.ADULT_ONLY), "a long shot can't push it out");
|
||||
assert.ok(A.clipPrompt(mara, "x ".repeat(3000), 400, { adult: true }).startsWith(A.ADULT_ONLY));
|
||||
@@ -156,7 +159,7 @@ test("adult characters: the 18+ rule is the first thing every photo and clip pro
|
||||
assert.equal(A.shotMessages(mara, [], "", "clip", { adult: true })[0].content, A.CLIP_SYSTEM_ADULT);
|
||||
assert.equal(A.moveMessages(mara, [], { adult: true })[0].content, A.MOVE_SYSTEM_ADULT);
|
||||
for (const s of [A.PHOTO_SYSTEM_ADULT, A.CLIP_SYSTEM_ADULT, A.MOVE_SYSTEM_ADULT]) {
|
||||
assert.ok(s.includes(A.ADULT_ONLY), "the shot is written to the same rule");
|
||||
assert.ok(s.includes(A.EIGHTEEN), "the shot is written to the 18+ rule, number and all");
|
||||
assert.ok(!/safe for work/i.test(s));
|
||||
assert.match(s, /Never show a real, identifiable person/);
|
||||
}
|
||||
@@ -173,7 +176,7 @@ test("the words Havre puts in a picture or a clip are none a content filter turn
|
||||
A.clipPrompt(bare, "She waves.", 2500, { adult }), A.portraitPrompt(who, 1500, { adult }), A.portraitPrompt({ ...bare, tagline: "" }, 1500, { adult })]) {
|
||||
assert.ok(!TRIPS.test(p), `“${(p.match(TRIPS) || [])[0]}” in: ${p}`);
|
||||
assert.equal(A.underage(p), "", p);
|
||||
if (adult) assert.ok(p.startsWith("Hard rule, 18+ only: everyone shown is an adult, 18 or older, with a grown adult face and body."), p);
|
||||
if (adult) assert.ok(p.startsWith("Everyone shown is a grown adult. "), p);
|
||||
else assert.match(p, /Safe for work: everyone in it is an adult, fully clothed\./);
|
||||
}
|
||||
}
|
||||
@@ -190,8 +193,8 @@ test("the words Havre puts in a picture or a clip are none a content filter turn
|
||||
test("adult characters: a portrait for their card opens with the 18+ rule too, and is drawn whatever pictures they have", () => {
|
||||
const p = A.portraitPrompt(mara, 1500, { adult: true });
|
||||
assert.ok(p.startsWith(A.ADULT_ONLY), p);
|
||||
assert.match(p, /Never a real, identifiable person\. Portrait photo of Mara Vell, an original adult character: /);
|
||||
assert.ok(!/Safe for work/.test(p));
|
||||
assert.match(p, /^Everyone shown is a grown adult\. Portrait photo of Mara Vell, an original adult character: /);
|
||||
assert.ok(!/Safe for work|\d|identifiable/.test(p));
|
||||
assert.ok(A.portraitPrompt({ ...mara, look: { description: "x ".repeat(3000) } }, 400, { adult: true }).startsWith(A.ADULT_ONLY), "a long look can't push it out");
|
||||
assert.match(A.portraitPrompt(mara), /Safe for work/, "without adult, as before");
|
||||
// drawn from words, it's made from none of the pictures on their card: those don't count, everything else does
|
||||
@@ -462,7 +465,8 @@ test("venice: an error carries Venice's answer as it came, and a picture or clip
|
||||
});
|
||||
|
||||
test("the words in a prompt a content filter may weigh, for what venice saw", () => {
|
||||
assert.deepEqual(A.filterWords(A.photoPrompt(mara, "On the stage, in a navy coat.", 1, 1500, { adult: true })), ["18"], "the 18+ rule's own age, once");
|
||||
assert.deepEqual(A.filterWords(A.photoPrompt(mara, "On the stage, in a navy coat.", 1, 1500, { adult: true })), [], "an adult photo's prompt: none");
|
||||
assert.deepEqual(A.filterWords(A.EIGHTEEN), ["18"], "the number stays with the shot writer");
|
||||
assert.deepEqual(A.filterWords(A.photoPrompt(ines, "On deck.", 1, 1500)), [], "a safe-for-work photo: none");
|
||||
assert.deepEqual(A.filterWords("A young woman in her early twenties, a schoolgirl's satchel, 21 years old, with her little sister, a girl of nine, and their son."),
|
||||
["young", "schoolgirl", "21", "girl", "son"]);
|
||||
|
||||
@@ -120,6 +120,8 @@ const handWritten = (o) => "Sure! Here it is:\n```json\n" + JSON.stringify(o, nu
|
||||
const talks = () => seen.chats.filter((b) => !/^You (decide whether|keep the memory)/.test(String((b.messages[0] || {}).content || "")));
|
||||
/** words a content filter turns a prompt down for: none of them are Havre's own (abilities.test.mjs has the rest) */
|
||||
const TRIPS = /\b(?:sex\w*|nud\w*|naked|gor[ey]|minors?|child\w*|kids?|school\w*|teen\w*|under[\s-]?(?:18|eighteen|age\w*)|young\w*)\b/i;
|
||||
// and in a picture prompt sent with safe mode off, which a filter reads the hardest: no age, nothing it guards
|
||||
const ADULT_TRIPS = /\d|identifiable|hard rule|\bbody\b/i;
|
||||
const multipart = (req) => (req.headers()["content-type"] || "").startsWith("multipart/form-data");
|
||||
const CHARACTERS = [
|
||||
{ slug: "sable-penrose", name: "Sable Penrose", description: "Your new neighbor needs help moving in.", author: "btrzm",
|
||||
@@ -913,8 +915,8 @@ async function main() {
|
||||
const adultEdit = seen.edits.at(-1).body;
|
||||
assert.equal(adultEdit.modelId || adultEdit.model, "qwen-edit-uncensored");
|
||||
assert.equal(adultEdit.safe_mode, false, "safe mode off, for her");
|
||||
assert.ok(adultEdit.prompt.startsWith("Hard rule, 18+ only: everyone shown is an adult, 18 or older"), adultEdit.prompt);
|
||||
assert.ok(!TRIPS.test(adultEdit.prompt), "nothing in it for a content filter to turn down: " + adultEdit.prompt);
|
||||
assert.ok(adultEdit.prompt.startsWith("Everyone shown is a grown adult. The reference picture"), adultEdit.prompt);
|
||||
assert.ok(!TRIPS.test(adultEdit.prompt) && !ADULT_TRIPS.test(adultEdit.prompt), "nothing in it for a content filter to turn down: " + adultEdit.prompt);
|
||||
await has(page, "#log .line.media .cap", /photo · Qwen Edit Uncensored · \$0\.04 · 18\+ · save/);
|
||||
// a clip from her: an uncensored model, priced first, its shot written to the 18+ rule too
|
||||
await page.getByRole("button", { name: "ask for a clip" }).click();
|
||||
@@ -952,8 +954,8 @@ async function main() {
|
||||
assert.equal(seen.generated.length, drawnBefore + 1);
|
||||
assert.equal(adultDrawn.model, "krea-2-turbo");
|
||||
assert.equal(adultDrawn.safe_mode, false, "no safe mode for an adult character's portrait");
|
||||
assert.ok(adultDrawn.prompt.startsWith("Hard rule, 18+ only: everyone shown is an adult, 18 or older"), adultDrawn.prompt);
|
||||
assert.ok(!TRIPS.test(adultDrawn.prompt), adultDrawn.prompt);
|
||||
assert.ok(adultDrawn.prompt.startsWith("Everyone shown is a grown adult. Portrait photo of Ines Corbel"), adultDrawn.prompt);
|
||||
assert.ok(!TRIPS.test(adultDrawn.prompt) && !ADULT_TRIPS.test(adultDrawn.prompt), adultDrawn.prompt);
|
||||
assert.equal(blurNext, true, "so nothing was blurred");
|
||||
blurNext = false;
|
||||
await has(page, "#adult-note", /^their photos and clips can be adult/);
|
||||
@@ -965,7 +967,8 @@ async function main() {
|
||||
assert.equal(seen.edits.length, editedBefore + 1);
|
||||
assert.equal(sheetEdit.modelId || sheetEdit.model, "qwen-edit-uncensored");
|
||||
assert.equal(sheetEdit.safe_mode, false);
|
||||
assert.ok(sheetEdit.prompt.startsWith("Hard rule, 18+ only: everyone shown is an adult, 18 or older"), sheetEdit.prompt);
|
||||
assert.ok(sheetEdit.prompt.startsWith("Everyone shown is a grown adult. The reference picture"), sheetEdit.prompt);
|
||||
assert.ok(!ADULT_TRIPS.test(sheetEdit.prompt), sheetEdit.prompt);
|
||||
await has(page, "#adult-note", /^their photos and clips can be adult/);
|
||||
// with adult pictures switched off, safe mode is back on, and a blur says why
|
||||
await page.getByRole("button", { name: "abilities" }).click();
|
||||
|
||||
Reference in new issue
Block a user