Utils and Helpers
This is a current map of shared utility modules under src/utils/.
Folder Map
Section titled “Folder Map”utils/asyncutils/audioutils/bridgesutils/cacheutils/chatutils/compactionutils/conditioningutils/dbutils/discordutils/documentsutils/embeddingsutils/imageutils/mcputils/mediautils/memoryutils/metricsutils/miscutils/novelaiutils/personautils/providerutils/quotautils/securityutils/storageutils/teachutils/textutils/tools
High-Impact Modules
Section titled “High-Impact Modules”utils/db
Section titled “utils/db”client.ts: DB client wiringinitializeDatabase.ts: schema + seed startup runnersqlSecurity.ts: query parameterisation helperssqlSplitter.ts: SQL file parsing utilitiesragAvailability.ts: pgvector / RAG feature detectionrepositories/: 28 domain-owned repository modules +index.ts(shared instance + type re-exports only). SQL remains in its owning module; no*ReadSql.ts/*WriteSql.tssibling files exist.ErrorLogRepositoryis a thin shim used bylogger.tsto insert intoerror_logswithout creating a circular import. Seedocs/en/architecture/subsystems/database-schema.mdfor the full repository table and SQL convention.
utils/discord
Section titled “utils/discord”commandLoader.ts: command discovery + localization wiringcommandRegistry.ts: runtime command maps used by handlersinteractionHelper.ts: compatibility barrel for grouped UI helpers inutils/discord/ui/; new code imports the owned UI module directlystreamOrchestrator.ts: public stream orchestration entry point backed by responsibility modules inutils/discord/stream/webhookManager.ts: compatibility barrel for grouped webhook helpers inutils/discord/webhook/; new code imports the owned webhook module directlyembedHelper.ts: shared embed builders (createStandardEmbed,createSummaryEmbed,createTipEmbed,sendStandardEmbed) — see Tip embeds belowhistoryFetcher.ts,historyFormatter.ts
Tip embeds
Section titled “Tip embeds”createTipEmbed(locale, tipKeys, tipVars?) in embedHelper.ts builds the reusable green 💡 Tip
embed shown alongside an error/info embed (e.g. by stream/errorUi.ts and ui/interactionCore.ts).
- Each entry in
tipKeysis an atomic locale key resolved independently and rendered as its own dashed bullet (- item). Keys live undergenai.tips.*(see the Localization doc’s Tip-item keys convention). - Tips render as an embed description, not a footer, so markdown and hyperlinks render — that is the reason tips moved out of error-embed footers.
- Conditional tips are the caller’s job: include or omit a key inline (e.g. an OpenRouter-only
item) instead of maintaining whole-paragraph tip strings per branch. Items that resolve to empty
text are dropped, and the function returns
nullwhen nothing resolves, so the caller can skip attaching a tip embed entirely. - The Official Support Server link is automatic:
genai.tips.support_server(exported asSUPPORT_SERVER_TIP_KEY) is appended as the last bullet of every rendered tip embed. Callers must not list it intipKeys— it is filtered out if they do, so it can never be duplicated or reordered. It is appended after the empty check, so a tip embed with no caller-supplied items still returnsnullrather than degrading into a support-link-only embed. - Colored
ColorCode.SUCCESS(green) to read as “helpful” and stay visibly distinct from the red/yellow error embed above it; the description is truncated to Discord’s embed-description limit.
utils/text
Section titled “utils/text”localizer.ts: locale auto-discovery + lookupcontextBuilder.ts: public structured context routing and native orchestrationcontext/: context-builder support modules for types, template/conditioning blocks, memories, RAG, and history/media helperscontextTruncator.ts: token-budget truncation strategyprocessors/regexUtils.ts:escapeRegExpprocessors/mentionProcessor.ts: mention resolution, template variables, emoji normalizationprocessors/llmOutputProcessor.ts: LLM output cleaning, speaker-turn truncationprocessors/chunkProcessor.ts: message chunking, sentence splittingprocessors/formatters.ts: time formatting, text humanization, boolean displayprocessors/timeUtils.ts: reminder time parsing, lateness calculationemojiHelper.ts,emojiPenalty.tstimezoneHelper.ts,uncensor.ts,youTubeUrlCleaner.ts
utils/cache
Section titled “utils/cache”tomoriStateCache.tsuserCache.tsemojiStickerCache.tschannelLlmCache.ts,channelLlmCacheStore.tschannelWhitelistCache.tsshortTermMemoryCache.tsllmCache.tsopenrouterCapabilityCache.tsgeminiCapabilityCache.tsnovelaiCapabilityCache.tsemergencyCacheClearer.ts: critical-memory cleanup for recoverable caches- lazy sync helpers (
emojiLazySync.ts,stickerLazySync.ts)
utils/security
Section titled “utils/security”secretsManager.ts:.envvs AWS Secrets Manager load pathkeyManager.ts: encryption key version managementcrypto.ts: encryption/decryption helperskeyRotation.ts: rotation workflowsrateLimiter.ts: upload quota cleanup schedulersafeDownload.ts: constrained external content downloadremoteUrlSecurity.ts: the single SSRF gate for user-supplied URLs (protocol/host policy, DNS resolution, blocklists)userRemoteFetch.ts: DNS-pinned fetch with per-hop redirect revalidation, built onremoteUrlSecurity.tscloudMetadata.ts: always-on cloud instance-metadata / link-local denylist
utils/quota
Section titled “utils/quota”imageQuotaManager.ts: per-user and server-wide image generation quotastextQuotaManager.ts: per-user and server-wide text trigger quotasvideoQuotaManager.ts: per-user and server-wide video generation quotas
utils/provider
Section titled “utils/provider”providerFactory.ts: provider auto-discovery and instance resolution
utils/mcp
Section titled “utils/mcp”mcpManager.ts: MCP lifecyclemcpExecutor.ts: MCP execution abstractionmcpConfig.ts: MCP config loading
Guild MCP URL validation lives in utils/security/remoteUrlSecurity.ts, which guards every user-supplied URL rather than MCP alone.
utils/bridges
Section titled “utils/bridges”bridgeUserId.ts: bridge ID and webhook username parsing utilitiesmatrix/: Matrix appservice bridge runtimematrix/events.ts: appservice init and Matrix inbound event surfacematrix/stateSync.ts: Matrix link cache, typing state, reminder mention surfacematrix/userMapping.ts: Matrix display-name/ID maps and persona intent surfacematrix/rooms.ts: Matrix room join/config/encryption helpersmatrix/index.ts: public Matrix exports grouped from the responsibility modules
New code should use utils/bridges for generic bridge helpers and utils/bridges/matrix for Matrix runtime operations.
utils/image and utils/storage
Section titled “utils/image and utils/storage”avatarHelper.ts,imageProcessor.ts,pngMetadata.tsavatarStorage.tsfor GCS or S3-compatible public avatar URL supportvoiceSampleStorage.tsfor GCS or S3-compatible voice sample storagecharrefStorage.tsfor NovelAI character reference storage (S3-compatible in production, local filesystem in non-production)S3_ENDPOINTenables Cloudflare R2 or another S3-compatible endpoint; when set, storage clients use path-style requests while public URLs still come from the relevant*_PUBLIC_BASE_URLvalue.
utils/misc
Section titled “utils/misc”logger.ts: structured logging facadeerrorContextStore.ts: ambient error identity (see below)ioHelper.ts: filesystem traversal helpershealthTracker.ts: runtime health signals used by/health
Ambient error context
Section titled “Ambient error context”log.error() and log.warn() accept an optional ErrorContext, but most call sites are far from
the code that knows which server or user they belong to. Threading that identity through every
signature is impractical, so errorContextStore.ts carries it out of band using an
AsyncLocalStorage scope.
The four entry points that begin a unit of work open a scope:
| Entry point | Opened in | source |
|---|---|---|
| Message chat turn | events/messageCreate/tomoriChat.ts |
chat |
| Slash command | events/interactionCreate/handleCommands.ts |
command |
| Scheduled reminder/task | timers/reminderProcessor.ts |
reminder |
| Random trigger | timers/randomTriggerProcessor.ts |
random_trigger |
Everything reached from inside a scope, at any await depth, logs with that identity attached. A provider adapter deep in a stream needs no plumbing to produce an attributable error record.
runWithErrorContext(identity, fn)opens a scope. Nested scopes inherit and override.enrichErrorContext(patch)upgrades the active scope once more IDs are known. Entry points seed Discord snowflakes; database row IDs are added after admission or user lookup resolves them.resolveErrorContext(explicit)is called by the logger. An explicit context wins per field, so a call site that names its own IDs stays authoritative.
Typed ErrorContext fields (serverId, userId, personaId) are database row IDs. Discord
snowflakes travel in metadata (serverDiscId, userDiscId, channelDiscId) alongside source
and sourceDetail, which identify the unit of work.
Timers and event handlers started outside a scope are unaffected, so background work that belongs to no server stays unattributed rather than inheriting a stale identity.
Usage Guidance
Section titled “Usage Guidance”- Prefer these shared modules over duplicating logic in commands/events.
- For user-facing responses, always pair utility usage with localization via
localizer(). - For DB writes touching cached data, invalidate the affected caches in the same code path.