puck / frontend /src /engine /chat.ts
vu1n's picture
Puck β€” desktop fairy familiar (HF Build Small)
3c124f3
Raw
History Blame Contribute Delete
1.89 kB
import type { FairyState, Rng } from "./types";
import { pick } from "./util";
// Keyword-routed scripted replies β€” the seam where a real model slots in later.
export function reply(text: string, fs: FairyState, rng: Rng = Math.random): string {
const q = text.toLowerCase();
const dramatic = fs.mischief > 60;
const pools: Record<string, string[]> = {
sleep: dramatic
? ["Tired already? Fine. Tuck me in and I'll dream us both smarter."]
: ["Say the word and I'll start Night Bloom. I sleep, I sort, I wake up a little different."],
memory: [
"Everything I keep lives in the garden β€” water it, prune it, pin it. I only plant what's durable.",
],
mischief: ["Crank the Goblin Weather and I get theatrical. Lower it and I behave. Mostly."],
claude: dramatic
? ["The code goblin on Desktop 2? I keep one eye on its scratching at all times."]
: ["I watch Claude closely. The moment it finishes, you'll hear from me."],
who: [
"I'm Puck. I'm not your assistant β€” I'm the thing that lives in the corners and patrols what you abandon.",
],
help: ["I help in the margins. Unfinished tasks, loud inboxes, builds that finish while you look away."],
discord: ["The social bog? I filter it hard. Mentions reach you. Swamp noise does not."],
thanks: ["Mm. I'll remember you said that.", "Plant it in the garden, then. A kindness."],
};
for (const k of Object.keys(pools)) if (q.includes(k)) return pick(pools[k], rng);
return pick(
[
"I heard you. I'm mostly watching the desktops you left behind, though.",
"Noted. I'll fold it into tonight's Night Bloom.",
dramatic
? "A fair point, for a human. I'll consider it while I patrol."
: "Got it. I'll keep that in mind on the next patrol.",
"I'm half-listening and fully loyal. Both at once.",
],
rng,
);
}