Commit Graph
7 Commits
Author SHA1 Message Date
asepharyana 5a70a685b4 fix(gateway): correct @/ alias import style (no .js) in archiveEmbedder
Gateway @/ alias imports use no .js extension (relative imports
keep .js). The .js suffix on @/ paths caused double-extension
ERR_MODULE_NOT_FOUND (embeddingClient.js.js) at runtime.
2026-08-18 15:44:18 +07:00
asepharyana 100b62800c fix(backend): drop .js extension on @/ alias imports (embed/qdrant)
Backend uses extensionless @/ alias imports; the double .js caused
ERR_MODULE_NOT_FOUND at runtime (index.js.js).
2026-08-18 15:19:05 +07:00
asepharyana 1ae19074ee feat(gmw): moderation explainability + semantic message search
- Persist structured verdict (flags/severity/confidence/evidence) on
  moderation_actions so the public web can show WHY a message was moderated.
- Add a persistent Qdrant archive collection (gmw_message_archive); embed
  every captured message at capture time (fire-and-forget, best-effort).
- Public semantic search over the archive (backend oRPC + FE toggle on the
  messages view). Both features are read-only/public and fully automatic.

Migration: 0015_add_moderation_explainability.sql
2026-08-18 15:11:01 +07:00
asepharyana d68f6b653a perf(ai-moderation): compact system prompt + memoize build + hoist vision pass
- Memoize buildSystemPrompt by (mode|channelCulture); identical signatures
  now reuse the ~5k-token core instead of rebuilding per sub-batch call
  (textBatchProcessor rebuilt it inside the loop; a 200-msg batch re-sent
  the full system prompt ~4x). Correction tail stays per-attempt (uncached).
- Hoist URL-image -> vision evidence out of the per-sub-batch loop in
  textBatchProcessor: it depends only on fetched images + full target set,
  so compute once per whole batch, not per sub-batch.
- Compact system instructions: collapse 3x-duplicated 'evaluate by content
  alone' statements into one standalone rule; trim output.ts channel-culture
  + context framing already covered by rules.ts/system.ts; drop duplicate
  programming-error-log few-shot (id 17, covered by rules AMAN list).
- Fix misleading config default: AI_LLM_BASE_URL default -> omniroute
  (gateway already runs omniroute via BWS; 9router was dead/misleading).

typecheck + lint + build green.
2026-08-18 11:49:39 +07:00
asepharyana 0cb0b82fb1 feat(messages): stream history one-message-per-WS-frame instead of 50-row batch
- backend: add streamMany generator (paginated, yields one record at a time)
  + messagesService.streamMessages + WS 'stream_messages' handler emitting
  'message_snapshot' per message, 'message_snapshot_end' with nextCursor
- frontend: useMessagesStream hook accumulates snapshots into SWR list,
  SSR getMessages seeds first paint, WsHook gains sendText
- add stream-many.test.ts locking the one-at-a-time + cursor contract
2026-08-18 10:21:08 +07:00
asepharyana b38616e051 fix(auto-delete): guard nickname reset on role hierarchy + surface LLM parse errors
- resetOffensiveNickname: skip when target role sits above bot
  (member.manageable) instead of hammering a doomed setNickname PATCH
  that Discord rejects with 50013 'Missing Permissions'. Log the
  Discord error code on failure for clear diagnosis.
- llmCaller: include contentPreview (first 200 chars) in the parse-
  failure warning so non-JSON LLM responses are debuggable.
2026-08-17 20:52:09 +07:00
asepharyana 479f4719ba refactor(ai): replace SearXNG with Wikipedia adapter for analysis enrichment
- Add wikipediaClient.ts: native fetch to Wikipedia REST/Action APIs
  (search + summary), no extra npm dependency.
- Extract shared Redis cache into cacheStore.ts (decoupled from search).
- Term glossary now uses wikipediaSummary for direct article lookup.
- Remove searxngSearch.ts entirely; drop SEARXNG_BASE_URL config,
  add WIKIPEDIA_LANG / WIKIPEDIA_TIMEOUT_MS.
- Rename backend searxngCalls metric to webSearchCalls.
2026-08-17 20:07:19 +07:00