fix: resolve architecture disconnects and codebase weaknesses

- Standardize MessageRecord types — single source of truth from @bete/shared
- Clean up config: remove unused GUILD_ID/TEXT_GUILD_ID/TEXT_CHANNEL_ID, fix WEBSERVER_PORT default (3001), remove default admin password
- Move mascot_chat_messages table to Drizzle schema with proper migration
- Remove runtime DDL (CREATE TABLE IF NOT EXISTS) from mascot-chat repository
- Remove phantom analytics/ module from documentation
- Add better-sqlite3 dependency to root devDependencies
- Replace 'as any' casts with proper type assertions across AI moderation
- Add error logging to silent catch blocks in LLM client
- Apply Biome formatting and import organization

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-09 13:07:01 +07:00
co-authored by Claude Opus 4.8
parent 67d66bb5dd
commit 3614d32701
21 changed files with 206 additions and 150 deletions
@@ -14,6 +14,24 @@ import { withLlmConcurrency } from "./concurrencyLimiter.js";
const log = createChildLogger("llm-client");
/**
* Covers all LLM response chunk shapes the streaming handler supports.
* Different providers (OpenAI, Anthropic-compatible, local LLMs) may return
* content in different fields — we try them all via optional chaining.
*/
type LLMResponseChunk = {
choices?: Array<{
delta?: { content?: string | null };
message?: { content?: string | null };
finish_reason?: string | null;
text?: string;
}>;
message?: { content?: string | null };
content?: string;
response?: string;
finish_reason?: string;
};
// ---------------------------------------------------------------------------
// Lazy singleton — created on first use so that config is always resolved.
// ---------------------------------------------------------------------------
@@ -112,7 +130,7 @@ export async function llmChat(
if (currentParams.stream) {
let content = "";
let finishReason = "stop";
for await (const chunk of response as any) {
for await (const chunk of response as unknown as AsyncIterable<LLMResponseChunk>) {
const choice = chunk?.choices?.[0];
const textChunk =
choice?.delta?.content ||