building out the components, updating the UI in overview and adding a little sqlite viewer
This commit is contained in:
@@ -7,12 +7,20 @@ import { useToast } from "./Toast";
|
||||
import { addGeneration, extractTitle, type Generation } from "../lib/generations";
|
||||
import { usePrefillEffect } from "../lib/usePrefill";
|
||||
|
||||
interface ItemMechanics {
|
||||
attunement: string; // "none", "yes", or a condition string
|
||||
charges: string; // "0" or "N (regen 1d6 per dawn)"
|
||||
value: string; // "500 gp"
|
||||
weight: string; // "2 lbs"
|
||||
effect: string; // one-line effect description
|
||||
}
|
||||
|
||||
interface ItemResponse {
|
||||
name: string;
|
||||
rarity: string;
|
||||
type: string;
|
||||
description: string;
|
||||
mechanical: string | Record<string, unknown>;
|
||||
mechanical: string | Record<string, unknown> | ItemMechanics;
|
||||
lore: string;
|
||||
}
|
||||
|
||||
@@ -67,11 +75,11 @@ The JSON must have exactly these keys:
|
||||
- "rarity": "${rarity}" (string)
|
||||
- "type": "${itemType}" (string)
|
||||
- "description": a vivid 2-3 sentence physical description (string)
|
||||
- "mechanical": the item's game mechanics as a single descriptive paragraph (string, NOT an object)
|
||||
- "mechanical": an object with keys attunement (string: "none", "yes", or a condition), charges (string), value (string), weight (string), and effect (a one-line string describing the item's mechanical effect)
|
||||
- "lore": a 1-2 sentence piece of lore or history (string)`,
|
||||
system: "You are a creative D&D item designer. You MUST respond with ONLY valid JSON. No markdown fences, no code blocks, no explanation. Just the JSON object.",
|
||||
temperature: 0.85,
|
||||
max_tokens: 500,
|
||||
max_tokens: 600,
|
||||
ragQuery: `${rarity} ${itemType} ${prompt}`,
|
||||
},
|
||||
});
|
||||
@@ -108,6 +116,12 @@ The JSON must have exactly these keys:
|
||||
};
|
||||
|
||||
const mechanicalText = item ? flattenValue(item.mechanical) : "";
|
||||
// ponytail: structured mechanics if the LLM returned the object form; fall
|
||||
// back to a paragraph string for older generations.
|
||||
const mech = item?.mechanical;
|
||||
const isStructured =
|
||||
typeof mech === "object" && mech !== null && "attunement" in mech && "effect" in mech;
|
||||
const structured = isStructured ? (mech as ItemMechanics) : null;
|
||||
const hasParseError = !item && rawResponse;
|
||||
|
||||
// ponytail: one-click "surprise me" — random rarity + type, no typed prompt.
|
||||
@@ -217,7 +231,24 @@ The JSON must have exactly these keys:
|
||||
|
||||
<div className="rounded-lg bg-[var(--color-bg-deep)] border border-[var(--color-border-glass)] p-3">
|
||||
<span className="text-[var(--color-gold-bright)] text-[10px] font-medium uppercase tracking-wider">Mechanics</span>
|
||||
<p className="text-[var(--color-text-primary)] text-sm mt-0.5">{mechanicalText}</p>
|
||||
{structured ? (
|
||||
<div className="mt-1 flex flex-col gap-1">
|
||||
{/* ponytail: structured fields — attunement/charges/value/weight + one-line effect */}
|
||||
<div className="flex flex-wrap gap-x-3 gap-y-0.5 text-xs">
|
||||
<span className="text-[var(--color-text-dim)]">Attunement: </span>
|
||||
<span className="text-[var(--color-text-primary)]">{structured.attunement === "none" || !structured.attunement ? "No" : structured.attunement}</span>
|
||||
<span className="text-[var(--color-text-dim)]">Charges: </span>
|
||||
<span className="text-[var(--color-text-primary)]">{structured.charges || "—"}</span>
|
||||
<span className="text-[var(--color-text-dim)]">Value: </span>
|
||||
<span className="text-[var(--color-text-primary)]">{structured.value || "—"}</span>
|
||||
<span className="text-[var(--color-text-dim)]">Weight: </span>
|
||||
<span className="text-[var(--color-text-primary)]">{structured.weight || "—"}</span>
|
||||
</div>
|
||||
<p className="text-[var(--color-text-primary)] text-sm mt-1">{structured.effect}</p>
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-[var(--color-text-primary)] text-sm mt-0.5">{mechanicalText}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user