Commit Graph
100 Commits
Author SHA1 Message Date
MythEclipse 8a712cff9b Refactor database handling to exclusively support PostgreSQL
- Removed SQLite support from the configuration and database initialization logic.
- Updated database migration scripts to focus solely on PostgreSQL migrations.
- Simplified logging messages to reflect PostgreSQL usage.
- Adjusted database schema definitions to remove SQLite-specific types and structures.
- Modified tests to ensure compatibility with PostgreSQL, including changes to table creation and data types.
- Cleaned up unused imports and code related to SQLite.
2026-05-31 15:46:18 +07:00
MythEclipse d1ef036358 feat(redis): integrate Redis for job queue management and persistent storage 2026-05-31 14:21:43 +07:00
MythEclipse ce945c8af0 fix(analytics): simplify GROUP BY and ORDER BY clauses in getDailyTrend function 2026-05-31 01:34:35 +07:00
MythEclipse 48b4123f58 chore: remove recharts dependency and clean up pnpm-lock.yaml
- Removed "recharts" from package.json and its associated entries from pnpm-lock.yaml.
- Cleaned up unnecessary dependencies and peer dependencies related to recharts and other unused packages.
2026-05-31 01:04:26 +07:00
MythEclipse 39e4e0ddc5 feat(analytics): refactor ActivityChart and TrendChart to use custom rendering and improve data visualization 2026-05-31 01:00:08 +07:00
MythEclipse 38ae6b03dd feat(analytics): add error boundary for AnalyticsPanel and improve loading state handling 2026-05-31 00:52:23 +07:00
MythEclipse 71e240c1e7 feat(analytics): add daily trend and activity heatmap endpoints, and implement corresponding frontend components
- Added new API endpoints for daily trend data and activity heatmap in analyticsRoutes.ts.
- Created new frontend components: ActivityChart, ControlBar, Heatmap, SummaryCards, TopicList, TrendChart, UserTable, and ViolatorTable for displaying analytics data.
- Implemented loading and empty states in the new components.
- Enhanced the existing moderation tests with remote fallback handling for Indonesian text normalization.
2026-05-31 00:41:34 +07:00
MythEclipse 4e9e370eb1 feat: enhance getTopViolators query to use conditional counts for improved accuracy in moderation stats 2026-05-30 21:29:16 +07:00
MythEclipse 10f44138bc feat: implement age restriction handling in message analysis and metadata 2026-05-30 21:12:25 +07:00
MythEclipse c9e79c8c7c feat: refactor database access in analyticsStore to use executeAll and executeGet for improved query handling 2026-05-30 20:40:33 +07:00
MythEclipse b19529f135 feat: enhance logging and moderation response handling with improved serialization and error management 2026-05-30 20:13:44 +07:00
MythEclipse b105f9748a refactor: optimize database queries and enhance caching for analytics 2026-05-30 17:28:27 +07:00
MythEclipseandClaude Opus 4.8 9a7b8f569d feat: make analytics real-time via WebSocket-triggered refresh
- Analytics panel now refreshes immediately when messages are created, updated, deleted, or analyzed
- WebSocket events (message_created, message_updated, message_deleted, message_analyzed) trigger custom event 'analytics_refresh'
- Analytics hook listens to 'analytics_refresh' event for instant updates
- Auto-refresh interval lowered from 60s to 5s as fallback
- Two-tier refresh: real-time push + 5s polling safety net

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:58:25 +07:00
MythEclipseandClaude Opus 4.8 fed9f39bd9 feat: rebrand to GMW — Discord Moderation Watcher
- New custom SVG logo: shield with eye + GMW text
- Page title: 'GMW — Discord Moderation Watcher'
- Header: shows logo + 'GMW · {tab title}'
- Sidebar: shows logo + 'GMW v1.0' + 'Discord Moderation Watcher'
- Favicon set to logo.svg
- Removed old 'Bete Watcher' branding

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:34:18 +07:00
MythEclipseandClaude Opus 4.8 c7abe39728 refactor: remove Review tab, make UI state client-side, fix Jakarta time in analytics
- Remove Review tab completely (was redundant with Messages flagged view)
- UI state now client-side only (localStorage) — no server API calls for tab/channel/guild selection
- Fixes dashboard crash when server is down — now loads fully client-side
- Live panel still uses server API for voice/media operations (only what needs it)
- Analytics hourly chart labels now show Jakarta time (WIB/UTC+7) instead of UTC
- Analytics formatTimeAgo uses Jakarta time reference
- Reduced tabs to 3: Live, Messages, Analytics
- Removed unused uiState API imports and server-side state fetching

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:31:27 +07:00
MythEclipseandClaude Opus 4.8 9019e24263 feat: merge Voice, Media, and Recordings into unified Live panel
- New LivePanel component combines voice bridge, media player, screen share, and recordings
- Single page layout: voice controls → audio visualizer + active speakers → now playing → music/screen/recordings tabs
- Reduced tabs from 6 to 4: Live, Messages, Analytics, Review
- Sidebar updated with new tab structure
- Default tab changed from 'voice' to 'live'
- Cleaner compact layout with icon buttons and inline controls
- Recordings sub-panel with user avatars, status badges, and download buttons

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:20:41 +07:00
MythEclipseandClaude Opus 4.8 c213300800 feat: redesign dashboard messages UI with better sticker/image display and AI filtering
MessageCard:
- Add sticker image preview (renders actual sticker from URL, not just text name)
- Show attachment thumbnails inline (up to 4 with overflow counter)
- Remove dead columns (ai_policy_version, ai_evidence) from UI
- Add severity color coding (critical=red, high=orange, medium=yellow, low=blue)
- Add relative time display ('2h ago' instead of full datetime)
- Better hover effects and visual hierarchy

MessagesPanel:
- Add stats bar showing total/clean/warn/flagged/error/pending/deleted/edited counts
- Add AI status filter buttons (all, clean, warn, flagged, error, pending)
- Improve search UX with inline search icon and clear button
- Show filtered count in tab labels

ImageGrid:
- Include sticker images (was only attachments + embeds before)
- Add kind badge overlay (sticker/attachment/embed)
- Show user avatar next to image caption
- Better sticker rendering (object-contain with padding)

Header:
- Add shield icon per tab
- Improve tab titles and add descriptive subtitles

API client:
- Remove dead fields from MessageRecord (ai_moderation_raw, ai_policy_version, ai_evidence)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:13:09 +07:00
MythEclipseandClaude Opus 4.8 a00a5a508f refactor: remove unused AI columns from messages table
Drop 3 columns that were written but never read:
- ai_moderation_raw: raw LLM JSON response (~KB per message, never consumed)
- ai_policy_version: hardcoded 'default-2026-05-30', never used for decisions
- ai_evidence: JSON evidence array, never read after write

Changes:
- schema.ts: remove columns from both Postgres and SQLite table definitions
- messageStore.ts: remove from AIAnalysisUpdate interface and SET clauses
- aiAnalyzer.ts: remove from individual fallback update calls
- aiAnalysisWorker.ts: remove raw write, add missing fields (categories, severity, etc.)
- types.ts: remove from MessageRecord interface
- analysisRoutes.ts: remove from reset analysis call
- New migration: src/database/migrations/001_drop_unused_ai_columns.sql
- Migration applied to live DB: 27 columns → 24 columns

Kept ai_error (useful for future debugging, currently 0 non-null)
Kept metadata (1.9MB total, used for AI sticker/embed evidence analysis)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 16:06:37 +07:00
MythEclipse 551d11ba82 Refactor code for improved readability and consistency
- Adjusted formatting in conversationContext.ts for better token estimation readability.
- Enhanced readability in indonesianTextNormalizer.ts by formatting multiline replacements.
- Reformatted badword lists and whitelists in indonesianTextNormalizer.ts for consistency.
- Improved function signatures in messageStore.ts for clarity.
- Reformatted messageCapture.ts to enhance readability of channel ID checks.
- Cleaned up error logging in messageStore.ts and retentionManager.ts for better clarity.
- Reformatted indonesianSlangLexicon.ts for consistent object formatting.
- Enhanced URL fetching regex patterns in urlFetcher.ts for better readability.
- Simplified query parameter destructuring in analyticsRoutes.ts for cleaner code.
- Improved test readability in autoDeleteManager.test.ts and indonesianTextNormalizer.test.ts by formatting expectations.
- Cleaned up whitespace in messageCaptureFilter.test.ts for consistency.
2026-05-30 15:55:01 +07:00
MythEclipseandClaude Opus 4.8 4fa7875b80 feat: add sticker context to LLM prompts + sticker image cache
- New sticker-specific vision prompt that tells LLM stickers are cartoon/meme art, not real photos
- New text-only warning for stickers that fail to download — prevents flagging based on name alone
- Updated system prompt with dedicated sticker guidance section (looser standards for cartoon content)
- Filesystem-backed sticker cache (keyed by name, 7-day TTL, 100MB max with LRU eviction)
- Config: STICKER_CACHE_DIR and STICKER_CACHE_MAX_SIZE_MB with defaults
- Updated .env.example with auto-delete + sticker config docs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 15:54:37 +07:00
MythEclipseandClaude Opus 4.8 202ea311a5 feat: lower auto-delete confidence threshold to 0.50, add allowed severities to defaults
- AUTO_DELETE_MIN_CONFIDENCE default 0.92 -> 0.50
- AUTO_DELETE_ALLOWED_SEVERITIES default 'critical' -> 'critical,high,medium'
- Add auto-delete config section to .env.example

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 15:35:07 +07:00
MythEclipse 8f6a35f591 feat: integrate NVIDIA Nemotron-3 Content Safety API for Indonesian badword detection
- Added configuration options for NVIDIA Nemotron API key, model, and base URL.
- Refactored badword detection to utilize NVIDIA API, with a fallback to a local badword list.
- Updated moderation functions to handle asynchronous operations for text evidence generation.
- Removed dependency on the `indonesian-badwords` package and implemented custom detection logic.
- Enhanced tests to accommodate asynchronous behavior and validate new detection methods.
2026-05-30 14:48:50 +07:00
MythEclipseandClaude Opus 4.6 3cc6b7a924 fix(auto-delete): derive severity/action from legacy fields, log at info level
- Derive severity from status/score when ai_severity missing
- Derive recommended_action from severity/status when field missing
- Upgrade skip logs from debug to info so skip reasons are visible
- Allow both 'flagged' and 'warn' status for eligibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-30 03:40:26 +07:00
MythEclipse 6eb83b864f feat(moderation): update auto-delete logic to include 'warn' status for message eligibility 2026-05-30 02:48:27 +07:00
MythEclipseandClaude Opus 4.6 29a186fea1 fix(db): add migration for AI moderation review schema
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-30 01:14:12 +07:00
MythEclipse d082cd850b Merge branch 'worktree-agent-acd4fe7096dc8d6e4' 2026-05-30 01:04:43 +07:00
MythEclipseandClaude Opus 4.6 c894e5cd75 feat: expand AI moderation with structured analysis, review workflow, and guardrails
- Add structured AI moderation fields (categories, severity, confidence,
  recommended_action, policy_version, evidence) to messages table
- Add moderation_reviews, moderation_actions, and retention_policies tables
- Upgrade LLM response parsing to support structured metadata with backwards
  compatibility for legacy responses
- Implement public AI evaluation review UI with decision controls
  (approve, false positive + reanalyze, escalate)
- Add auto-delete guardrails requiring high confidence, severity, and
  allowed categories; log all attempts to moderation_actions
- Add retention manager scaffolding for messages/attachments/voice
- Add action executor for moderation actions (mute, warn, kick, ban)
- Add review routes: GET/POST/PATCH /api/reviews, GET/POST/PATCH /api/actions
- Preserve auth separation: voice/media/recordings gated, review public

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-30 01:02:51 +07:00
MythEclipse 394bd5a471 feat(moderation): skip message capture for specific channels in shouldCaptureMessageLocation 2026-05-30 00:37:20 +07:00
MythEclipse b938420eb3 feat(moderation): enhance Indonesian slang lexicon with additional profanity normalization and expand badword detection logic 2026-05-30 00:14:28 +07:00
MythEclipse d03244a0ae feat(moderation): update lexicon to include sexual deviation topics and clarify analysis guidelines 2026-05-30 00:01:09 +07:00
MythEclipse 81606f49a5 feat(moderation): enhance Indonesian slang lexicon with profanity normalization 2026-05-29 23:59:38 +07:00
MythEclipse 9ed50bc8ed feat(ui): add "analytics" tab to activeTabs and defaultSharedUIState 2026-05-29 21:10:00 +07:00
MythEclipse 687fcec62c chore: add comment to clarify app initialization process 2026-05-29 20:54:57 +07:00
MythEclipse 8c3bb77984 feat: add analytics hooks and routes for moderation statistics
- Implemented `useAnalytics` hook for fetching and managing analytics data.
- Created `analyticsStore.ts` to handle database queries for hourly stats, topic trends, user leaderboard, and moderation stats.
- Added Express routes for analytics endpoints including overview, hourly stats, topic trends, user leaderboard, moderation stats, and top violators.
- Introduced a utility function `filterHits` for filtering specific terms in text.
2026-05-29 19:37:08 +07:00
MythEclipseandClaude Opus 4.8 fb09ac81c5 feat(moderation): Indonesian slang normalizer and false-positive prevention
- Add indonesian-badwords dependency for local lexical signal
- Add Indonesian slang lexicon with woy/woi/hadeh as safe casual terms
- Normalize Discord custom emoji <:name:id> to [emoji:name] in prompts
- Wire normalization evidence into both conversationContext and llmModerationClient prompts
- Harden system prompt: woy/woi are casual greetings, not SARA/hate
- Add tests for emoji normalization, slang mapping, badword detection

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 18:39:10 +07:00
MythEclipse b96fb619c9 feat(config): change default value of boolean to false in config schema 2026-05-29 18:12:28 +07:00
MythEclipseandClaude Opus 4.8 7da83387ee feat(moderation): auto-delete flagged messages
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 18:04:42 +07:00
MythEclipse 649283a3bc feat(moderation): enhance media analysis handling and integrate image evidence 2026-05-29 17:43:34 +07:00
MythEclipse 2b1c436b3e feat(moderation): enhance media evidence handling and deferral analysis rejection 2026-05-29 17:32:04 +07:00
MythEclipse 0e9890db79 chore: remove node-datachannel submodule in favor of npm package 2026-05-29 15:37:43 +07:00
MythEclipse 82e77d9f12 fix(moderation): update Traefik router rule to use correct host 2026-05-29 13:15:56 +07:00
MythEclipse f624eea94b fix(moderation): update Traefik router rule to use correct hosts 2026-05-29 03:46:38 +07:00
MythEclipse 130f13e8a7 fix(moderation): update Traefik router rule to use correct host 2026-05-29 02:52:41 +07:00
MythEclipse 441ff5a0ed feat(moderation): fetch and analyze URLs (images and web text) from messages
- Added  to safely extract and fetch up to 3 URLs per message (with SSRF protection, 5MB limit, and 8s timeout).
- Implemented recursive  extraction to resolve Tenor/Giphy links from their HTML viewers to raw GIF binaries.
- In , fetched images are automatically injected as  into the vision LLM context, and truncated webpage text is appended to the message string.
2026-05-28 01:29:31 +07:00
MythEclipse c6af313c33 fix(moderation): immediately abort retries on 429 Too Many Requests
- In llmModerationClient.ts (inner retry), if OpenAI throws a 429 (or 401/403), throw p-retry's AbortError to immediately exit the 3-attempt inner retry loop.
- In aiAnalyzer.ts (outer retry), propagate the AbortError from runModerationAnalysis so the 2-attempt outer retry loop also aborts immediately.
- This ensures that a burst of 20 concurrent tasks hitting rate limits immediately returns the messages to the DB queue (as 'analysis_incomplete') and rapidly increments the individual circuit breaker, pausing processing and preventing a thundering herd instead of making 12 API calls per stuck message.
2026-05-28 01:09:57 +07:00
MythEclipse 9976e66ca5 fix(moderation): patch 3 additional aiAnalyzer vulnerabilities
Infinite recovery loop (#new):
  - Inside retryWithBackoff callback in processIndividualFallback, detect
    'analysis_incomplete' in the LLM result and throw to trigger backoff.
  - Track exhaustedOnIncomplete flag across retries.
  - On final exhaustion: write terminal flag 'individual_analysis_exhausted'
    to DB so the recovery query (which only looks for 'analysis_incomplete')
    never picks this message up again.
  - Transient failures (network/parse) are NOT written as exhausted; they
    remain as 'analysis_incomplete' and are retried via the CB-throttled
    recovery cycle.

Token budget zero-result deadlock (#10):
  - If pickBatchWithinBudget returns [] because every candidate message
    individually exceeds AI_ANALYSIS_MAX_TARGET_TOKENS, fall back to
    messages.slice(0,1) so at least the first message is processed.
  - Without this, messages would be permanently stuck as 'pending' because
    every recovery tick would fetch them, trim to 0, and exit silently.
  - Uses messages.slice(0,1) instead of messages[0]! to avoid the
    forbidden noNonNullAssertion lint rule.

Stale state map memory leak (#9):
  - startPendingAIAnalysisWorker now prunes conversationErrorCooldown and
    conversationProcessing on every recovery interval tick.
  - Cooldown entries past their expiry timestamp are deleted.
  - Processing entries older than AI_ANALYSIS_PROCESSING_TIMEOUT_MS are
    deleted (these represent stale locks from crashed processing runs).
  - Prevents unbounded Map growth for long-running bots with many channels.

Batch/individual scheduling collision (#8):
  - Build incompleteKeySet (Set<string>) from incompleteKeys before the
    batch recovery loop.
  - Batch recovery loop skips any key present in incompleteKeySet so a
    conversation that has both 'pending' and 'analysis_incomplete' messages
    is only targeted by the individual pipeline, not both simultaneously.
  - Avoids the DB last-write-wins race where batch and individual pipelines
    both update the same message rows concurrently.
2026-05-28 00:07:55 +07:00
MythEclipse 61045aabc8 fix(moderation): patch 6 aiAnalyzer audit vulnerabilities
#1+#5 - Individual fallback circuit breaker
  - Add individualConsecutiveErrors + individualCooldownUntil (30s)
  - On success: reset counter; on failure: increment + trip at
    AI_ANALYSIS_INDIVIDUAL_CB_THRESHOLD (default 10) consecutive errors
  - enqueueIndividualFallbacks checks CB before admitting any work

#1 - Individual fallback concurrency cap
  - enqueueIndividualFallbacks enforces AI_ANALYSIS_INDIVIDUAL_MAX_CONCURRENT
    (default 20); overflow stays as error/analysis_incomplete in DB and is
    recovered by the recovery worker on the next interval

#3 - Unhandled rejection in async setTimeout
  - scheduleConversationAnalysis no longer uses async arrow in setTimeout;
    all async work is chained with .then()/.catch() explicitly

#4 - Recovery worker ignores individualInFlight
  - Add individualInFlightByConversation Map<conversationKey, count>
  - processIndividualFallback increments/decrements it in try/finally
  - startPendingAIAnalysisWorker skips conversations present in the map
  - Recovery worker also processes error/analysis_incomplete messages via
    two new messageStore queries: getConversationKeysWithIncompleteAnalysis
    and getIncompleteMessagesByConversation

#6 - pickBatchWithinBudget never called
  - scheduleConversationAnalysis now calls pickBatchWithinBudget with
    AI_ANALYSIS_MAX_TARGET_TOKENS (default 4000) + 50-token per-msg overhead
    after fetching messages, before passing to processBatch

#7 - AI_PROCESSING_OVERLAP_MS 30s shorter than max LLM retry window
  - Replace hardcoded 30 000 ms constant with configurable
    AI_ANALYSIS_PROCESSING_TIMEOUT_MS (default 120 000 ms)
  - LLM client: 30s timeout × 3 retries + backoff ≈ 90-100s; 120s is safe

New config keys:
  AI_ANALYSIS_PROCESSING_TIMEOUT_MS   (default: 120000)
  AI_ANALYSIS_INDIVIDUAL_MAX_CONCURRENT (default: 20)
  AI_ANALYSIS_INDIVIDUAL_CB_THRESHOLD  (default: 10)
  AI_ANALYSIS_MAX_TARGET_TOKENS        (default: 4000)

New AnalysisQueueStatus fields:
  activeIndividualRequests, individualInFlightCount,
  individualCircuitBreakerActive
2026-05-27 23:32:38 +07:00
MythEclipse 5925c11c54 feat(moderation): two-tier batch+individual fallback pipeline
- After a batch LLM call, any result flagged analysis_incomplete is
  immediately fanned out to an individual per-message fallback queue
- Batch hard-fail (result.ok=false) and unhandled exceptions now also
  route all affected messages to the individual queue instead of waiting
  behind the conversation error cooldown
- Individual queue runs fully parallel (fire-and-forget per message),
  de-duplicated by a Set<messageId> so no double-processing
- processIndividualFallback runs in the main process (no worker pool IPC
  overhead for a single-item call), with retryWithBackoff 2x/2-15s
- AnalysisQueueStatus gains activeIndividualRequests +
  individualInFlightCount fields for dashboard observability
2026-05-27 23:25:37 +07:00
MythEclipse 2156c52c35 feat: add OpenAI integration with custom header logging and request aborting 2026-05-26 01:34:37 +07:00
MythEclipse c1c149855a feat: enforce strict AI env validation and force close 2026-05-26 00:59:32 +07:00
MythEclipse 7126959548 fix: bypass Cloudflare WAF 403 blocks by spoofing User-Agent and removing X-Stainless headers 2026-05-26 00:03:01 +07:00
MythEclipse cc61e2576b refactor: optimize AI moderation pipeline, fix OOM risks, token duplication, and add Zod validation 2026-05-25 23:23:12 +07:00
MythEclipse cc2ee84c3b refactor(ai-analyzer): fix resource leaks, OOM risk, and strict structured outputs 2026-05-25 22:14:05 +07:00
MythEclipse c32b5274e9 chore: update dependencies and configuration
- Added @discordjs/opus and opusscript to package.json and pnpm-lock.yaml.
- Updated pnpm-workspace.yaml to allow builds for @discordjs/opus.
- Imported dotenv in config.ts for environment variable management.
- Created .npmrc to manage npm configurations.
2026-05-24 20:06:36 +07:00
MythEclipse 34b15e20dc chore(vendor): update discord-video-stream to latest commit from fork 2026-05-23 17:38:48 +07:00
MythEclipseandClaude Opus 4.7 2183955133 chore(submodules): update all submodule URLs to point to MythEclipse forks
Update all vendor submodules to use forks under MythEclipse account:
- vendor/discord-video-stream
- vendor/drizzle-orm
- vendor/better-sqlite3
- vendor/node-datachannel

This ensures all submodules are under your control and can be updated
independently without relying on upstream repositories.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 17:38:34 +07:00
MythEclipse 246919cfa0 chore(vendor): update discord-video-stream subproject to latest commit 2026-05-23 17:36:09 +07:00
MythEclipseandClaude Opus 4.7 9b49c05f32 fix(streaming): quote User-Agent header to prevent ffmpeg argument splitting
The ffmpeg -headers option was receiving the User-Agent value split across
multiple arguments due to spaces not being properly quoted. This caused ffmpeg
to interpret "Mozilla/5.0" as an output format, resulting in:
  [NULL @ ...] Unable to find a suitable output format for 'Mozilla/5.0'

Fixed by wrapping the entire headers string in quotes so parseArgsStringToArgv
treats it as a single argument. The headers string is now properly passed to
ffmpeg as: -headers "User-Agent: ... \r\nConnection: ..."

The fix has been applied to vendor/discord-video-stream/src/media/newApi.ts
and compiled into dist/media/newApi.js. A patch file and documentation have
been added to the patches/ directory for reference.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 17:35:42 +07:00
MythEclipseandClaude Opus 4.7 f2b476e1f0 fix(streaming): quote User-Agent header to prevent ffmpeg argument splitting
The ffmpeg -headers option was receiving the User-Agent value split across
multiple arguments due to spaces not being properly quoted. This caused ffmpeg
to interpret "Mozilla/5.0" as an output format, resulting in:
  [NULL @ ...] Unable to find a suitable output format for 'Mozilla/5.0'

Fixed by wrapping the entire headers string in quotes so parseArgsStringToArgv
treats it as a single argument. The headers string is now properly passed to
ffmpeg as: -headers "User-Agent: ... \r\nConnection: ..."

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 17:31:21 +07:00
MythEclipse 4ec9b50f33 fix(moderation): interleave images with owning messages, Indonesian-first prompt
- Replace flat imageParts prologue with per-message image map (messageImageMap)
  keyed by message_id. Images are now inserted immediately after their owning
  message's text part in the multimodal content array, giving the vision model
  proper text+image co-context instead of a disconnected image dump before the
  entire prompt.

- Rewrite moderationPrompt as Indonesian-first bilingual system prompt:
  * Primary language: Bahasa Indonesia; English secondary
  * Explicit Discord community context with Indonesian slang awareness
    (anjay, wkwk, santuy, gw/lo abbreviations, etc.)
  * SARA, hoaks, ujaran kebencian cultural context
  * Charitable intent for ambiguous Indonesian phrasing
  * Expanded flag taxonomy: sara, hoaks, nsfw_image, gore_image, doxxing, scam
  * analysis field instructed in Bahasa Indonesia (maks 2 kalimat)
  * Retry/correction messages also in Bahasa Indonesia

- Image instruction block conditionally injected into prompt only when
  hasImages=true, explicitly telling model to treat image + preceding text
  as one semantic unit and to OCR meme/screenshot text as message content.
2026-05-22 01:04:00 +07:00
MythEclipse d0e906763e fix(moderation): fix image attachment pipeline causing PIL BadRequestError on NVIDIA inference
Three-layer defect chain causing 'cannot identify image file <_io.BytesIO object>':

1. attachmentUploader: hardcoded 'application/octet-stream' on Tele CDN upload
   regardless of actual file MIME type — CDN stored images under wrong type.

2. messageCapture: processAttachmentUpload call site never forwarded
   attachment.contentType into the options bag, so the fix in (1) would
   have received undefined and fallen back to octet-stream anyway.

3. llmModerationClient: blindly trusted att.type from the DB record
   (Discord-provided MIME) when constructing data: URLs, but validated
   neither the HTTP status of the CDN re-fetch nor the actual byte content.
   Stale/expired CDN URLs returning HTML error pages were base64-encoded
   and sent to the model as 'image/jpeg', causing PIL to reject the stream.

Fixes:
- uploadAttachmentToTele now accepts contentType param (defaults to
  application/octet-stream for non-image files)
- processAttachmentUpload options bag gains optional contentType field
- messageCapture forwards attachment.contentType at the call site
- Added sniffImageMimeType() using magic-byte probes for JPEG, PNG, GIF,
  WebP, AVIF/HEIF — runs on every downloaded attachment buffer before
  base64 encoding; skips the attachment (logs headerHex for diagnosis)
  if bytes don't match a known image format
- data: URL now uses the sniffed MIME type, not the DB record
2026-05-21 23:44:18 +07:00
MythEclipse 834b19b1ae feat(moderation): enhance JSON extraction and validation in moderation analysis 2026-05-21 04:23:01 +07:00
MythEclipse f851ea0fa9 fix(moderation): improve error handling for malformed JSON responses and ensure proper response headers 2026-05-21 04:00:36 +07:00
MythEclipse 8884e29ce7 feat(recordings): add RecordingsPanel component for displaying voice recordings 2026-05-21 03:56:44 +07:00
MythEclipse 5588ece6c7 feat(moderation): normalize JSON response handling and enhance test coverage for moderation analysis 2026-05-21 03:52:51 +07:00
MythEclipse 419018ab0c fix(vendor): update discord-video-stream subproject commit reference 2026-05-21 03:28:08 +07:00
MythEclipse c1c3c99686 feat(moderation): improve message analysis scheduling and update moderation prompt structure 2026-05-21 02:56:41 +07:00
MythEclipse 7eb01606b7 feat(moderation): enhance attachment handling and AI analysis integration 2026-05-21 02:39:28 +07:00
MythEclipse 3d64228d6a feat(config): add AI analysis tuning parameters and update related logic 2026-05-21 01:55:50 +07:00
MythEclipse 5fb7b2ce24 docs: add CodeGraph usage guidelines to CLAUDE.md 2026-05-21 00:52:28 +07:00
MythEclipse d0259ddae0 fix(vendor): update discord-video-stream subproject commit reference 2026-05-21 00:45:50 +07:00
MythEclipse c349736b89 refactor(messageStore): simplify message query conditions and pagination logic
chore(package): remove unused pnpm configuration
2026-05-21 00:45:35 +07:00
MythEclipse 480bcff5e2 feat(logging): add error serialization and log metadata formatting
- Introduced `loggerSerialization.ts` to handle error serialization and log metadata formatting.
- Added `serializeError` function to convert Error objects into a structured format.
- Implemented `serializeLogValue` to handle various data types including Errors, Dates, RegExps, and plain objects.
- Created `formatLogMetadata` to format log metadata using the serialization functions.

feat(pagination): implement cursor encoding and decoding

- Added `pagination.ts` to manage cursor-based pagination.
- Implemented `encodeCursor` to convert cursor data into a base64 string.
- Developed `decodeCursor` to parse base64 strings back into cursor data, with error handling for invalid inputs.
2026-05-21 00:34:30 +07:00
MythEclipseandClaude Opus 4.7 31e8de3185 fix: add missing discord-video-stream package.json to Docker build context
The Dockerfile was only copying discord.js-selfbot-v13/package.json but not
discord-video-stream/package.json before running pnpm install. This caused
pnpm to fail with ERR_PNPM_WORKSPACE_PKG_NOT_FOUND since @dank074/discord-video-stream
is declared as a workspace dependency but its package.json wasn't available.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 17:49:14 +07:00
MythEclipse 12424e5391 chore: update pnpm workspace configuration and vendor subproject
- Added allowBuilds for specific packages in pnpm-workspace.yaml
- Excluded certain minimum release ages for packages
- Updated onlyBuiltDependencies list
- Marked discord.js-selfbot-v13 subproject as dirty
2026-05-19 16:48:06 +07:00
MythEclipse 2821b4cfae fix: allow pnpm install to proceed without frozen lockfile in Dockerfile 2026-05-19 16:36:13 +07:00
MythEclipse 80957d1eb3 fix: update Docker image tag to use commit SHA for versioning 2026-05-19 16:34:23 +07:00
MythEclipse 4687443fd4 fix: remove unused GITHUB_TOKEN and REPO_URL from deployment workflow 2026-05-19 16:31:28 +07:00
MythEclipse 0fe61e0634 fix: update permissions in deploy workflow and correct GITHUB_TOKEN reference 2026-05-19 16:15:50 +07:00
MythEclipse b51210f9b0 a 2026-05-19 16:07:50 +07:00
MythEclipse a12abaccd6 refactor: configure git safe directory for deployment 2026-05-19 16:01:14 +07:00
MythEclipse b9d75ce9a0 refactor: update deployment process to use git clone for VPS 2026-05-19 15:52:47 +07:00
MythEclipse e8e0697a84 chore: clean dependencies and format restructure 2026-05-19 15:12:09 +07:00
MythEclipse dcbe204795 refactor: extract application bootstrap 2026-05-19 15:08:02 +07:00
MythEclipse f7c8257ef1 refactor: move webserver orchestration 2026-05-19 14:58:09 +07:00
MythEclipseandClaude Opus 4.7 d98bf1a5fe refactor: extract http app setup
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 14:52:52 +07:00
MythEclipse 109a6825bc refactor: extract websocket server 2026-05-19 14:45:39 +07:00
MythEclipse d52803ae20 refactor: extract browser audio bridge 2026-05-19 14:34:24 +07:00
MythEclipse c3f7291543 refactor: isolate websocket globals 2026-05-19 14:26:06 +07:00
MythEclipse 3639028f6f refactor: extract media settings state 2026-05-19 14:16:00 +07:00
MythEclipse a1b85d8ac3 refactor: extract persisted ui state 2026-05-19 14:11:09 +07:00
MythEclipse f48f62893d refactor: extract pcm audio helpers 2026-05-19 13:56:36 +07:00
MythEclipse 7f5db953fa chore: update dependencies and improve code formatting
- Added `vendor/discord-video-stream` to pnpm workspace.
- Refactored `llmModerationClient.ts` for better readability and consistency.
- Adjusted imports in `recordingsRoutes.ts` for clarity.
- Updated `webserver.ts` to correctly import `createRecordingsRoutes`.
- Enhanced test cases in `llmModerationClient.test.ts` for improved readability.
- Updated submodule references for `better-sqlite3`, `discord-video-stream`, `discord.js-selfbot-v13`, `drizzle-orm`, and `node-datachannel`.
- Created documentation for deprecated dependency removal plan and design.
2026-05-19 02:49:55 +07:00
MythEclipse e85967ae51 style: format winston logger changes 2026-05-19 02:48:37 +07:00
MythEclipse f0b4f2cd56 chore: ignore runtime log files 2026-05-19 02:44:42 +07:00
MythEclipse f8ba4b41e9 fix: preserve structured logger metadata 2026-05-19 02:43:52 +07:00
MythEclipse 1aa8c6a370 refactor: normalize logger call sites for winston 2026-05-19 02:39:18 +07:00
MythEclipseandClaude Opus 4.7 2ab097a0c3 chore: switch logging dependency to winston
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 02:20:03 +07:00
MythEclipse 0e08d29df3 test: cover logger metadata serialization 2026-05-19 02:16:50 +07:00
MythEclipseandClaude Opus 4.7 97648604d7 docs: add Winston logging refactor design spec
Design for migrating from Pino to Winston with hybrid console/file logging,
npm-standard log levels, and dependency cleanup.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 02:06:45 +07:00