- 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.
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>
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>
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>
- 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.
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
- Changed all import statements across the project to include the .js extension for consistency and to comply with ES module standards.
- Updated imports in various files including bootstrap.ts, shutdown.ts, config.ts, and many others.
- Ensured that all related modules and types are correctly imported with the new extension.
- 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.
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>
- 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