cleanup and fix ci

This commit is contained in:
2026-01-10 21:52:11 -05:00
parent 1059eced53
commit c48188792d
5 changed files with 27 additions and 18 deletions

View File

@@ -130,7 +130,7 @@ function extractCanonicalNames(dungeonData) {
// Extract faction names from core concepts (if available) // Extract faction names from core concepts (if available)
if (dungeonData.coreConcepts) { if (dungeonData.coreConcepts) {
const factionMatch = dungeonData.coreConcepts.match(/Primary Faction[:\s]+([^\.]+)/i); const factionMatch = dungeonData.coreConcepts.match(/Primary Faction[:\s]+([^.]+)/i);
if (factionMatch) { if (factionMatch) {
names.factions.push(factionMatch[1].trim()); names.factions.push(factionMatch[1].trim());
} }
@@ -472,7 +472,7 @@ Output as five separate numbered lists with these exact labels: "Locations:", "E
// Step 6: Player Choices and Consequences // Step 6: Player Choices and Consequences
const npcNamesList = npcs.map(n => n.name).join(", "); const npcNamesList = npcs.map(n => n.name).join(", ");
const factionName = coreConcepts.match(/Primary Faction[:\s]+([^\.]+)/i)?.[1]?.trim() || "the primary faction"; const factionName = coreConcepts.match(/Primary Faction[:\s]+([^.]+)/i)?.[1]?.trim() || "the primary faction";
const plotResolutionsRaw = await callOllama( const plotResolutionsRaw = await callOllama(
`Based on all of the following elements, suggest 4-5 possible, non-conflicting story climaxes or plot resolutions for adventurers exploring this location. Each resolution must provide a meaningful choice with a tangible consequence, directly related to the Central Conflict, the Primary Faction, or the NPCs. `Based on all of the following elements, suggest 4-5 possible, non-conflicting story climaxes or plot resolutions for adventurers exploring this location. Each resolution must provide a meaningful choice with a tangible consequence, directly related to the Central Conflict, the Primary Faction, or the NPCs.

View File

@@ -19,13 +19,6 @@ export function dungeonTemplate(data) {
"'Playfair Display', serif" "'Playfair Display', serif"
]; ];
const tableFonts = [
"'Alegreya Sans', sans-serif",
"'Cabin', sans-serif",
"'IBM Plex Sans', sans-serif",
"'Cormorant Garamond', serif"
];
const quoteFonts = [ const quoteFonts = [
"'Playfair Display', serif", "'Playfair Display', serif",
"'Libre Baskerville', serif", "'Libre Baskerville', serif",
@@ -34,7 +27,6 @@ export function dungeonTemplate(data) {
const bodyFont = pickRandom(bodyFonts); const bodyFont = pickRandom(bodyFonts);
const headingFont = pickRandom(headingFonts); const headingFont = pickRandom(headingFonts);
const tableFont = pickRandom(tableFonts);
const quoteFont = pickRandom(quoteFonts); const quoteFont = pickRandom(quoteFonts);
// Check if we have a map image to include // Check if we have a map image to include

View File

@@ -26,7 +26,7 @@ export async function generatePDF(data, outputPath = "dungeon.pdf") {
const imageData = data.map ? await readImageData(data.map) : null; const imageData = data.map ? await readImageData(data.map) : null;
const dataWithImage = imageData const dataWithImage = imageData
? { ...data, map: imageData } ? { ...data, map: imageData }
: (({ map, ...rest }) => rest)(data); : (({ map, ...rest }) => rest)(data); // eslint-disable-line no-unused-vars
const html = dungeonTemplate(dataWithImage); const html = dungeonTemplate(dataWithImage);
await page.setContent(html, { waitUntil: "networkidle0" }); await page.setContent(html, { waitUntil: "networkidle0" });

View File

@@ -167,6 +167,9 @@ async function waitForImage(promptId, timeout = 900000) {
while (Date.now() - start < timeout) { while (Date.now() - start < timeout) {
const res = await fetch(`${COMFYUI_URL}/history`); const res = await fetch(`${COMFYUI_URL}/history`);
if (!res.ok) {
throw new Error(`ComfyUI history request failed: ${res.status} ${res.statusText}`);
}
const data = await res.json(); const data = await res.json();
const historyEntry = data[promptId]; const historyEntry = data[promptId];
@@ -206,7 +209,7 @@ async function generateImageViaComfyUI(prompt, filename) {
}); });
if (!res.ok) { if (!res.ok) {
throw new Error(`ComfyUI error: ${res.statusText}`); throw new Error(`ComfyUI error: ${res.status} ${res.statusText}`);
} }
const { prompt_id } = await res.json(); const { prompt_id } = await res.json();

View File

@@ -12,7 +12,10 @@ function cleanText(str) {
} }
function inferApiType(url) { function inferApiType(url) {
return url?.includes("/api/chat/completions") ? "open-webui" : "direct"; if (!url) return "ollama-generate";
if (url.includes("/api/chat/completions")) return "open-webui";
if (url.includes("/api/chat")) return "ollama-chat";
return "ollama-generate";
} }
async function sleep(ms) { async function sleep(ms) {
@@ -21,6 +24,7 @@ async function sleep(ms) {
async function callOllamaBase(prompt, model, retries, stepName, apiType) { async function callOllamaBase(prompt, model, retries, stepName, apiType) {
const isUsingOpenWebUI = apiType === "open-webui"; const isUsingOpenWebUI = apiType === "open-webui";
const isUsingOllamaChat = apiType === "ollama-chat";
for (let attempt = 1; attempt <= retries; attempt++) { for (let attempt = 1; attempt <= retries; attempt++) {
try { try {
@@ -39,7 +43,7 @@ async function callOllamaBase(prompt, model, retries, stepName, apiType) {
headers["Authorization"] = `Bearer ${OLLAMA_API_KEY}`; headers["Authorization"] = `Bearer ${OLLAMA_API_KEY}`;
} }
const body = isUsingOpenWebUI const body = isUsingOpenWebUI || isUsingOllamaChat
? { model, messages: [{ role: "user", content: prompt }] } ? { model, messages: [{ role: "user", content: prompt }] }
: { model, prompt, stream: false }; : { model, prompt, stream: false };
@@ -49,15 +53,25 @@ async function callOllamaBase(prompt, model, retries, stepName, apiType) {
body: JSON.stringify(body), body: JSON.stringify(body),
}); });
if (!response.ok) if (!response.ok) {
let errorDetails = "";
try {
const errorData = await response.text();
errorDetails = errorData ? `: ${errorData}` : "";
} catch {
// Ignore errors reading error response
}
throw new Error( throw new Error(
`Ollama request failed: ${response.status} ${response.statusText}`, `Ollama request failed: ${response.status} ${response.statusText}${errorDetails}`,
); );
}
const data = await response.json(); const data = await response.json();
const rawText = isUsingOpenWebUI const rawText = isUsingOpenWebUI
? data.choices?.[0]?.message?.content ? data.choices?.[0]?.message?.content
: data.response; : isUsingOllamaChat
? data.message?.content
: data.response;
if (!rawText) throw new Error("No response from Ollama"); if (!rawText) throw new Error("No response from Ollama");
@@ -92,7 +106,7 @@ export async function callOllamaExplicit(
model = OLLAMA_MODEL, model = OLLAMA_MODEL,
retries = 5, retries = 5,
stepName = "unknown", stepName = "unknown",
apiType = "direct", apiType = "ollama-generate",
) { ) {
return callOllamaBase(prompt, model, retries, stepName, apiType); return callOllamaBase(prompt, model, retries, stepName, apiType);
} }