initial 2
Some checks failed
CI / test (push) Has been cancelled

This commit is contained in:
2026-06-26 09:26:50 +01:00
parent 194330fb47
commit 3b37368e7d
213 changed files with 14688 additions and 1 deletions

View File

@@ -0,0 +1,124 @@
import { parseAiJson } from "./parse-json";
export function safeParseAiJson(raw: string): unknown | null {
try {
return parseAiJson(raw);
} catch {
return null;
}
}
export function normalizeTeacherPayload(data: unknown): unknown {
if (!data || typeof data !== "object") return data;
const o = data as Record<string, unknown>;
const flashcards = Array.isArray(o.flashcards)
? o.flashcards
.map((c) => {
if (!c || typeof c !== "object") return null;
const card = c as Record<string, unknown>;
const front = String(card.front ?? "").trim();
const back = String(card.back ?? "").trim();
if (!front && !back) return null;
return { front, back };
})
.filter(Boolean)
: [];
const quiz = Array.isArray(o.quiz)
? o.quiz
.map((q) => {
if (!q || typeof q !== "object") return null;
const item = q as Record<string, unknown>;
const options = Array.isArray(item.options)
? item.options.map((opt) => String(opt))
: [];
if (options.length === 0) return null;
let answer = Number(item.answer ?? 0);
if (!Number.isFinite(answer)) answer = 0;
if (answer < 0 || answer >= options.length) answer = 0;
return {
question: String(item.question ?? "Question"),
options,
answer,
};
})
.filter(Boolean)
: [];
return {
title: o.title != null ? String(o.title) : undefined,
introduction: o.introduction != null ? String(o.introduction) : undefined,
objectives: Array.isArray(o.objectives)
? o.objectives.map(String).filter(Boolean)
: undefined,
readingSteps: Array.isArray(o.readingSteps)
? o.readingSteps.map(String).filter(Boolean)
: undefined,
reflectionPrompt:
o.reflectionPrompt != null ? String(o.reflectionPrompt) : undefined,
flashcards,
quiz,
assignment: String(o.assignment ?? o.homework ?? "").trim(),
};
}
export function normalizeExplorationPayload(data: unknown): unknown {
if (!data || typeof data !== "object") return data;
const o = data as Record<string, unknown>;
const items = Array.isArray(o.explorations)
? o.explorations
: Array.isArray(o.quests)
? o.quests
: [];
return {
explorations: items
.map((item) => {
if (!item || typeof item !== "object") return null;
const e = item as Record<string, unknown>;
const title = String(e.title ?? "").trim();
if (!title) return null;
const minutes = Number(e.minutes ?? e.duration ?? 20);
return {
title,
hook: String(e.hook ?? e.description ?? e.reason ?? title).trim(),
category: String(e.category ?? "general").trim(),
minutes: Number.isFinite(minutes) && minutes > 0 ? minutes : 20,
};
})
.filter(Boolean),
};
}
export function debugAiLog(
location: string,
message: string,
data: Record<string, unknown>
) {
console.error(`[adventureos-ai] ${location}: ${message}`, JSON.stringify(data));
// #region agent log
fetch("http://127.0.0.1:7257/ingest/abfa22e4-3d86-4176-9679-7c59b1f0489f", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Debug-Session-Id": "04e12c",
},
body: JSON.stringify({
sessionId: "04e12c",
location,
message,
data,
timestamp: Date.now(),
}),
}).catch(() => {});
// #endregion
}
export function isAiTimeoutError(error: unknown): boolean {
if (!(error instanceof Error)) return false;
if (error.name === "TimeoutError") return true;
if (error.message.toLowerCase().includes("timeout")) return true;
return (error as Error & { code?: number }).code === 23;
}