From a607661a71d8d06b4d2d932ce37d811a5a79b9c9 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 1 May 2026 18:44:46 +0100 Subject: [PATCH] refactor: trim qqbot helper exports --- extensions/qqbot/src/engine/adapter/index.ts | 13 ------------- .../src/engine/adapter/mention-gate.port.ts | 6 +----- extensions/qqbot/src/engine/approval/index.ts | 6 +++--- .../commands/builtin/register-clear-storage.ts | 2 +- .../src/engine/commands/slash-commands-impl.ts | 8 -------- .../qqbot/src/engine/commands/slash-commands.ts | 4 ++-- .../qqbot/src/engine/gateway/event-dispatcher.ts | 2 +- .../src/engine/gateway/gateway-connection.ts | 2 +- .../qqbot/src/engine/gateway/message-queue.ts | 8 ++++---- .../src/engine/gateway/outbound-dispatch.ts | 2 +- extensions/qqbot/src/engine/gateway/reconnect.ts | 2 +- extensions/qqbot/src/engine/gateway/types.ts | 6 +++--- .../qqbot/src/engine/gateway/typing-keepalive.ts | 4 ++-- extensions/qqbot/src/engine/group/activation.ts | 2 +- extensions/qqbot/src/engine/group/history.ts | 6 +++--- extensions/qqbot/src/engine/group/mention.ts | 4 ++-- .../qqbot/src/engine/group/message-gating.ts | 2 +- .../qqbot/src/engine/messaging/media-source.ts | 4 ++-- .../src/engine/messaging/media-type-detect.ts | 2 +- .../src/engine/messaging/outbound-deliver.ts | 16 ++++++++-------- .../src/engine/messaging/reply-dispatcher.ts | 12 ++++-------- .../qqbot/src/engine/messaging/reply-limiter.ts | 2 +- extensions/qqbot/src/engine/messaging/sender.ts | 12 +++--------- .../qqbot/src/engine/messaging/streaming-c2c.ts | 4 ++-- .../src/engine/messaging/streaming-media-send.ts | 2 +- .../qqbot/src/engine/messaging/target-parser.ts | 4 ++-- extensions/qqbot/src/engine/tools/channel-api.ts | 2 +- .../qqbot/src/engine/tools/remind-logic.ts | 10 +++++----- .../qqbot/src/engine/utils/attachment-tags.ts | 4 ++-- extensions/qqbot/src/engine/utils/diagnostics.ts | 2 +- extensions/qqbot/src/engine/utils/file-utils.ts | 6 +++--- extensions/qqbot/src/engine/utils/image-size.ts | 2 +- extensions/qqbot/src/engine/utils/payload.ts | 4 ++-- extensions/qqbot/src/engine/utils/platform.ts | 2 +- .../qqbot/src/engine/utils/request-context.ts | 2 +- .../qqbot/src/engine/utils/string-normalize.ts | 2 +- extensions/qqbot/src/engine/utils/stt.ts | 2 +- 37 files changed, 70 insertions(+), 105 deletions(-) diff --git a/extensions/qqbot/src/engine/adapter/index.ts b/extensions/qqbot/src/engine/adapter/index.ts index aab74858452..61448f3a8ac 100644 --- a/extensions/qqbot/src/engine/adapter/index.ts +++ b/extensions/qqbot/src/engine/adapter/index.ts @@ -29,19 +29,6 @@ import type { FetchMediaOptions, FetchMediaResult, SecretInputRef } from "./types.js"; -// ============ Re-exports (port interfaces) ============ - -export type { HistoryPort, HistoryEntryLike } from "./history.port.js"; -export type { - MentionGatePort, - MentionFacts, - MentionPolicy, - MentionGateDecision, - ImplicitMentionKind, -} from "./mention-gate.port.js"; -export type { AudioConvertPort, OutboundAudioPort } from "./audio.port.js"; -export type { CommandsPort, ApproveRuntimeGetter } from "./commands.port.js"; - // ============ EngineAdapters (aggregated port injection) ============ /** diff --git a/extensions/qqbot/src/engine/adapter/mention-gate.port.ts b/extensions/qqbot/src/engine/adapter/mention-gate.port.ts index c4c0c788b5b..f31609aa932 100644 --- a/extensions/qqbot/src/engine/adapter/mention-gate.port.ts +++ b/extensions/qqbot/src/engine/adapter/mention-gate.port.ts @@ -8,11 +8,7 @@ */ /** Implicit mention kind aligned with SDK's `InboundImplicitMentionKind`. */ -export type ImplicitMentionKind = - | "reply_to_bot" - | "quoted_bot" - | "bot_thread_participant" - | "native"; +type ImplicitMentionKind = "reply_to_bot" | "quoted_bot" | "bot_thread_participant" | "native"; /** Facts about the current message's mention state. */ export interface MentionFacts { diff --git a/extensions/qqbot/src/engine/approval/index.ts b/extensions/qqbot/src/engine/approval/index.ts index 4dbe8ff8fff..c873e9a2f2f 100644 --- a/extensions/qqbot/src/engine/approval/index.ts +++ b/extensions/qqbot/src/engine/approval/index.ts @@ -42,14 +42,14 @@ export interface PluginApprovalRequest { }; } -export type ApprovalDecision = "allow-once" | "allow-always" | "deny"; +type ApprovalDecision = "allow-once" | "allow-always" | "deny"; -export interface ApprovalTarget { +interface ApprovalTarget { type: ChatScope; id: string; } -export interface ParsedApprovalAction { +interface ParsedApprovalAction { approvalId: string; decision: ApprovalDecision; } diff --git a/extensions/qqbot/src/engine/commands/builtin/register-clear-storage.ts b/extensions/qqbot/src/engine/commands/builtin/register-clear-storage.ts index e1fa8c988de..2bdbdc4aa56 100644 --- a/extensions/qqbot/src/engine/commands/builtin/register-clear-storage.ts +++ b/extensions/qqbot/src/engine/commands/builtin/register-clear-storage.ts @@ -81,7 +81,7 @@ const CLEAR_STORAGE_MAX_DISPLAY = 10; * under `~/.openclaw/media/qqbot/downloads/` without appId subdivision. * The clear-storage command therefore cleans the entire downloads root. */ -export function resolveQqbotDownloadsDir(): string { +function resolveQqbotDownloadsDir(): string { return getQQBotMediaPath("downloads"); } diff --git a/extensions/qqbot/src/engine/commands/slash-commands-impl.ts b/extensions/qqbot/src/engine/commands/slash-commands-impl.ts index a4b71bc3eb2..51c49e5a16e 100644 --- a/extensions/qqbot/src/engine/commands/slash-commands-impl.ts +++ b/extensions/qqbot/src/engine/commands/slash-commands-impl.ts @@ -31,14 +31,6 @@ export function initCommands(port: CommandsPort): void { initSlashCommandDeps(port); } -export type { - SlashCommandContext, - SlashCommandResult, - SlashCommandFileResult, - QQBotFrameworkCommand, - QueueSnapshot, -} from "./slash-commands.js"; - /** * Return all commands that require authorization, for registration with the * framework via api.registerCommand() in registerFull(). diff --git a/extensions/qqbot/src/engine/commands/slash-commands.ts b/extensions/qqbot/src/engine/commands/slash-commands.ts index f000a3737bf..d313f4545b5 100644 --- a/extensions/qqbot/src/engine/commands/slash-commands.ts +++ b/extensions/qqbot/src/engine/commands/slash-commands.ts @@ -58,14 +58,14 @@ export interface QueueSnapshot { export type SlashCommandResult = string | SlashCommandFileResult | null; /** Slash command result that sends text first and then a local file. */ -export interface SlashCommandFileResult { +interface SlashCommandFileResult { text: string; /** Local file path to send. */ filePath: string; } /** Slash command definition. */ -export interface SlashCommand { +interface SlashCommand { /** Command name without the leading slash. */ name: string; /** Short description. */ diff --git a/extensions/qqbot/src/engine/gateway/event-dispatcher.ts b/extensions/qqbot/src/engine/gateway/event-dispatcher.ts index 3dee2fcf802..d704184ce6f 100644 --- a/extensions/qqbot/src/engine/gateway/event-dispatcher.ts +++ b/extensions/qqbot/src/engine/gateway/event-dispatcher.ts @@ -20,7 +20,7 @@ import type { // ============ Dispatch result ============ -export type DispatchResult = +type DispatchResult = | { action: "ready"; data: unknown; sessionId: string } | { action: "resumed"; data: unknown } | { action: "message"; msg: QueuedMessage } diff --git a/extensions/qqbot/src/engine/gateway/gateway-connection.ts b/extensions/qqbot/src/engine/gateway/gateway-connection.ts index 8060e03b58c..841f03edf84 100644 --- a/extensions/qqbot/src/engine/gateway/gateway-connection.ts +++ b/extensions/qqbot/src/engine/gateway/gateway-connection.ts @@ -31,7 +31,7 @@ import type { GatewayAccount, EngineLogger, GatewayPluginRuntime, WSPayload } fr // ============ Connection context ============ -export interface GatewayConnectionContext { +interface GatewayConnectionContext { account: GatewayAccount; abortSignal: AbortSignal; cfg: unknown; diff --git a/extensions/qqbot/src/engine/gateway/message-queue.ts b/extensions/qqbot/src/engine/gateway/message-queue.ts index 1e83d659337..928700d0c00 100644 --- a/extensions/qqbot/src/engine/gateway/message-queue.ts +++ b/extensions/qqbot/src/engine/gateway/message-queue.ts @@ -53,7 +53,7 @@ export interface QueuedMention { * representative turn, the merge information lands here instead of * being scattered across `_` -prefixed fields on {@link QueuedMessage}. */ -export interface QueuedMergeInfo { +interface QueuedMergeInfo { /** Number of original messages folded in. Always >= 2. */ count: number; /** Original messages in insertion order — `messages.at(-1)` is "current". */ @@ -129,7 +129,7 @@ export function isMergedTurn(msg: QueuedMessage): msg is QueuedMessage & { return (msg.merge?.count ?? 0) > 1; } -export interface MessageQueueContext { +interface MessageQueueContext { accountId: string; log?: { info: (msg: string, meta?: Record) => void; @@ -149,14 +149,14 @@ export interface MessageQueueContext { } /** Snapshot of the queue state for diagnostics. */ -export interface QueueSnapshot { +interface QueueSnapshot { totalPending: number; activeUsers: number; maxConcurrentUsers: number; senderPending: number; } -export interface MessageQueue { +interface MessageQueue { enqueue: (msg: QueuedMessage) => void; startProcessor: (handleMessageFn: (msg: QueuedMessage) => Promise) => void; getSnapshot: (senderPeerId: string) => QueueSnapshot; diff --git a/extensions/qqbot/src/engine/gateway/outbound-dispatch.ts b/extensions/qqbot/src/engine/gateway/outbound-dispatch.ts index ab3c89d2335..771eb7e0b74 100644 --- a/extensions/qqbot/src/engine/gateway/outbound-dispatch.ts +++ b/extensions/qqbot/src/engine/gateway/outbound-dispatch.ts @@ -49,7 +49,7 @@ const TOOL_MEDIA_SEND_TIMEOUT = 45_000; // ============ Dependencies ============ -export interface OutboundDispatchDeps { +interface OutboundDispatchDeps { runtime: GatewayPluginRuntime; cfg: unknown; account: GatewayAccount; diff --git a/extensions/qqbot/src/engine/gateway/reconnect.ts b/extensions/qqbot/src/engine/gateway/reconnect.ts index 32d4fd50c0d..8f21c74b0dc 100644 --- a/extensions/qqbot/src/engine/gateway/reconnect.ts +++ b/extensions/qqbot/src/engine/gateway/reconnect.ts @@ -18,7 +18,7 @@ import { } from "./constants.js"; /** Actions the caller should take after processing a close event. */ -export interface CloseAction { +interface CloseAction { /** Whether to schedule a reconnect. */ shouldReconnect: boolean; /** Custom delay override (ms), or undefined to use the default backoff. */ diff --git a/extensions/qqbot/src/engine/gateway/types.ts b/extensions/qqbot/src/engine/gateway/types.ts index ec6ea48456d..a2902e8eb7d 100644 --- a/extensions/qqbot/src/engine/gateway/types.ts +++ b/extensions/qqbot/src/engine/gateway/types.ts @@ -120,7 +120,7 @@ export interface WSPayload { } /** Attachment shape shared by all message event types. */ -export interface RawMessageAttachment { +interface RawMessageAttachment { content_type: string; url: string; filename?: string; @@ -129,7 +129,7 @@ export interface RawMessageAttachment { } /** Referenced message element (used for quote messages). */ -export interface RawMsgElement { +interface RawMsgElement { msg_idx?: string; content?: string; attachments?: Array< @@ -203,7 +203,7 @@ import type { EngineAdapters } from "../adapter/index.js"; * future additions (admin lookup, proactive push, per-group toggles) * don't keep polluting the top-level context type. */ -export interface GatewayGroupOptions { +interface GatewayGroupOptions { /** * Whether group-chat gating is enabled. Defaults to `true`; set to * `false` to disable all group processing (e.g. for a DM-only smoke diff --git a/extensions/qqbot/src/engine/gateway/typing-keepalive.ts b/extensions/qqbot/src/engine/gateway/typing-keepalive.ts index c385651803b..254c43eaf5e 100644 --- a/extensions/qqbot/src/engine/gateway/typing-keepalive.ts +++ b/extensions/qqbot/src/engine/gateway/typing-keepalive.ts @@ -8,7 +8,7 @@ import { formatErrorMessage } from "../utils/format.js"; /** Function that sends a typing indicator to one user. */ -export type SendInputNotifyFn = ( +type SendInputNotifyFn = ( token: string, openid: string, msgId: string | undefined, @@ -16,7 +16,7 @@ export type SendInputNotifyFn = ( ) => Promise; /** Refresh every 50s for the QQ API's 60s input-notify window. */ -export const TYPING_INTERVAL_MS = 50_000; +const TYPING_INTERVAL_MS = 50_000; export const TYPING_INPUT_SECOND = 60; export class TypingKeepAlive { diff --git a/extensions/qqbot/src/engine/group/activation.ts b/extensions/qqbot/src/engine/group/activation.ts index 805def36212..6e011cbfd77 100644 --- a/extensions/qqbot/src/engine/group/activation.ts +++ b/extensions/qqbot/src/engine/group/activation.ts @@ -88,7 +88,7 @@ export function resolveGroupActivation(params: { * 2. `$OPENCLAW_STATE_DIR` / `$CLAWDBOT_STATE_DIR` * 3. `~/.openclaw/agents/{agentId}/sessions/sessions.json` */ -export function resolveSessionStorePath( +function resolveSessionStorePath( cfg: Record, agentId: string | undefined, ): string { diff --git a/extensions/qqbot/src/engine/group/history.ts b/extensions/qqbot/src/engine/group/history.ts index 0f051fb15c0..e1779fd02a7 100644 --- a/extensions/qqbot/src/engine/group/history.ts +++ b/extensions/qqbot/src/engine/group/history.ts @@ -59,10 +59,10 @@ const MAX_HISTORY_KEYS = 1000; * attachments (group history cache, ref-index store, and the dynamic * context block on the current message) all share a single shape. */ -export type AttachmentSummary = RefAttachmentSummary; +type AttachmentSummary = RefAttachmentSummary; /** Raw attachment fields carried in a QQ event (the union we actually read). */ -export interface RawAttachment { +interface RawAttachment { content_type: string; filename?: string; /** Pre-computed ASR transcription text provided by QQ's gateway. */ @@ -83,7 +83,7 @@ export interface HistoryEntry { } /** Parameters for {@link formatMessageContent}. */ -export interface FormatMessageContentParams { +interface FormatMessageContentParams { content: string; /** Message channel — `stripMentionText` only fires for `"group"`. */ chatType?: string; diff --git a/extensions/qqbot/src/engine/group/mention.ts b/extensions/qqbot/src/engine/group/mention.ts index 161b0989514..f1ef462c34e 100644 --- a/extensions/qqbot/src/engine/group/mention.ts +++ b/extensions/qqbot/src/engine/group/mention.ts @@ -42,7 +42,7 @@ export interface RawMention { } /** Input for {@link detectWasMentioned}. */ -export interface DetectWasMentionedInput { +interface DetectWasMentionedInput { /** * Raw event type. `"GROUP_AT_MESSAGE_CREATE"` unambiguously identifies * that the bot was @-ed, even when the mentions array is empty. @@ -59,7 +59,7 @@ export interface DetectWasMentionedInput { } /** Input for {@link hasAnyMention}. */ -export interface HasAnyMentionInput { +interface HasAnyMentionInput { mentions?: RawMention[]; content?: string; } diff --git a/extensions/qqbot/src/engine/group/message-gating.ts b/extensions/qqbot/src/engine/group/message-gating.ts index 8e7951ad265..1a31147540a 100644 --- a/extensions/qqbot/src/engine/group/message-gating.ts +++ b/extensions/qqbot/src/engine/group/message-gating.ts @@ -41,7 +41,7 @@ * skip AI dispatch. * - `pass` — forward the message to the AI pipeline. */ -export type GroupMessageGateAction = +type GroupMessageGateAction = | "drop_other_mention" | "block_unauthorized_command" | "skip_no_mention" diff --git a/extensions/qqbot/src/engine/messaging/media-source.ts b/extensions/qqbot/src/engine/messaging/media-source.ts index 7ced94cad9b..cdae52dc4f6 100644 --- a/extensions/qqbot/src/engine/messaging/media-source.ts +++ b/extensions/qqbot/src/engine/messaging/media-source.ts @@ -73,7 +73,7 @@ const DATA_URL_RE = /^data:([^;,]+);base64,(.+)$/i; * base64 encoding. Non-base64 data URLs are intentionally rejected because * the QQ upload API ingests raw base64, not arbitrary URL-encoded payloads. */ -export function tryParseDataUrl(value: string): { mime: string; data: string } | null { +function tryParseDataUrl(value: string): { mime: string; data: string } | null { if (!value.startsWith("data:")) { return null; } @@ -92,7 +92,7 @@ export function tryParseDataUrl(value: string): { mime: string; data: string } | * * Callers MUST call {@link OpenedLocalFile.close} (typically in a `finally`). */ -export interface OpenedLocalFile { +interface OpenedLocalFile { handle: fs.promises.FileHandle; size: number; close(): Promise; diff --git a/extensions/qqbot/src/engine/messaging/media-type-detect.ts b/extensions/qqbot/src/engine/messaging/media-type-detect.ts index 469d03703c6..87e5fe321a0 100644 --- a/extensions/qqbot/src/engine/messaging/media-type-detect.ts +++ b/extensions/qqbot/src/engine/messaging/media-type-detect.ts @@ -11,7 +11,7 @@ const VIDEO_EXTENSIONS = new Set([".mp4", ".mov", ".avi", ".mkv", ".webm", ".flv /** * Extract a lowercase file extension from a path or URL, ignoring query and hash. */ -export function getCleanExtension(filePath: string): string { +function getCleanExtension(filePath: string): string { const cleanPath = filePath.split("?")[0].split("#")[0]; const lastDot = cleanPath.lastIndexOf("."); if (lastDot < 0) { diff --git a/extensions/qqbot/src/engine/messaging/outbound-deliver.ts b/extensions/qqbot/src/engine/messaging/outbound-deliver.ts index 87fc033210d..4d441d06a85 100644 --- a/extensions/qqbot/src/engine/messaging/outbound-deliver.ts +++ b/extensions/qqbot/src/engine/messaging/outbound-deliver.ts @@ -28,7 +28,7 @@ import { // ---- Injected dependency interfaces ---- /** Media target context — describes where to send media. */ -export interface MediaTargetContext { +interface MediaTargetContext { targetType: "c2c" | "group" | "channel" | "dm"; targetId: string; account: GatewayAccount; @@ -36,14 +36,14 @@ export interface MediaTargetContext { } /** Media send result. */ -export interface MediaSendResult { +interface MediaSendResult { channel?: string; error?: string; messageId?: string; } /** Media sender interface — implemented by the upper-layer outbound.ts module. */ -export interface MediaSender { +interface MediaSender { sendPhoto(target: MediaTargetContext, imageUrl: string): Promise; sendVoice( target: MediaTargetContext, @@ -75,7 +75,7 @@ export interface DeliverDeps { /** Maximum text length for a single QQ Bot message. */ const TEXT_CHUNK_LIMIT = 5000; -export interface DeliverEventContext { +interface DeliverEventContext { type: "c2c" | "guild" | "dm" | "group"; senderId: string; messageId: string; @@ -85,7 +85,7 @@ export interface DeliverEventContext { msgIdx?: string; } -export interface DeliverAccountContext { +interface DeliverAccountContext { account: GatewayAccount; qualifiedTarget: string; log?: { @@ -96,10 +96,10 @@ export interface DeliverAccountContext { } /** Wrapper that retries when the access token expires. */ -export type SendWithRetryFn = (sendFn: (token: string) => Promise) => Promise; +type SendWithRetryFn = (sendFn: (token: string) => Promise) => Promise; /** Consume a quote ref exactly once. */ -export type ConsumeQuoteRefFn = () => string | undefined; +type ConsumeQuoteRefFn = () => string | undefined; // ---- Internal helpers ---- @@ -458,7 +458,7 @@ export async function parseAndSendMediaTags( // ---- Plain reply ---- -export interface PlainReplyPayload { +interface PlainReplyPayload { text?: string; mediaUrls?: string[]; mediaUrl?: string; diff --git a/extensions/qqbot/src/engine/messaging/reply-dispatcher.ts b/extensions/qqbot/src/engine/messaging/reply-dispatcher.ts index 114b698c2c2..67ce67bf7bd 100644 --- a/extensions/qqbot/src/engine/messaging/reply-dispatcher.ts +++ b/extensions/qqbot/src/engine/messaging/reply-dispatcher.ts @@ -32,7 +32,7 @@ import { // ---- Injected dependencies ---- /** TTS provider interface — injected from the outer layer. */ -export interface TTSProvider { +interface TTSProvider { /** Framework TTS: text → audio file path. */ textToSpeech(params: { text: string; @@ -57,7 +57,7 @@ export interface ReplyDispatcherDeps { // ---- Exported types ---- -export interface MessageTarget { +interface MessageTarget { type: "c2c" | "guild" | "dm" | "group"; senderId: string; messageId: string; @@ -66,7 +66,7 @@ export interface MessageTarget { groupOpenid?: string; } -export interface ReplyContext { +interface ReplyContext { target: MessageTarget; account: GatewayAccount; cfg: unknown; @@ -93,11 +93,7 @@ export async function sendWithTokenRetry( // ---- Text routing ---- /** Route a text message to the correct QQ target type. */ -export async function sendTextToTarget( - ctx: ReplyContext, - text: string, - refIdx?: string, -): Promise { +async function sendTextToTarget(ctx: ReplyContext, text: string, refIdx?: string): Promise { const { target, account } = ctx; const deliveryTarget = buildDeliveryTarget(target); const creds = accountToCreds(account); diff --git a/extensions/qqbot/src/engine/messaging/reply-limiter.ts b/extensions/qqbot/src/engine/messaging/reply-limiter.ts index a86c19186dc..bfa0cd6b575 100644 --- a/extensions/qqbot/src/engine/messaging/reply-limiter.ts +++ b/extensions/qqbot/src/engine/messaging/reply-limiter.ts @@ -11,7 +11,7 @@ */ /** Configuration for the reply limiter. */ -export interface ReplyLimiterConfig { +interface ReplyLimiterConfig { /** Maximum passive replies per message. Defaults to 4. */ limit?: number; /** TTL in milliseconds for the passive reply window. Defaults to 1 hour. */ diff --git a/extensions/qqbot/src/engine/messaging/sender.ts b/extensions/qqbot/src/engine/messaging/sender.ts index 82b5fbecebc..356eae120e5 100644 --- a/extensions/qqbot/src/engine/messaging/sender.ts +++ b/extensions/qqbot/src/engine/messaging/sender.ts @@ -50,9 +50,6 @@ import { normalizeSource, type MediaSource, type RawMediaSource } from "./media- // ============ Re-exported types ============ -export { ApiError } from "../types.js"; -export type { OutboundMeta, MessageResponse, UploadMediaResponse } from "../types.js"; -export { MediaFileType } from "../types.js"; export { UploadDailyLimitExceededError } from "../api/media-chunked.js"; // ============ Plugin User-Agent ============ @@ -357,7 +354,7 @@ export interface DeliveryTarget { } /** Account credentials for API authentication. */ -export interface AccountCreds { +interface AccountCreds { appId: string; clientSecret: string; } @@ -528,7 +525,7 @@ export function createRawInputNotifyFn( // ============ Media sending (unified) ============ /** Rich-media kind accepted by {@link sendMedia}. */ -export type MediaKind = "image" | "voice" | "video" | "file"; +type MediaKind = "image" | "voice" | "video" | "file"; /** Map a {@link MediaKind} to the wire-level {@link MediaFileType} code. */ const KIND_TO_FILE_TYPE: Record = { @@ -538,16 +535,13 @@ const KIND_TO_FILE_TYPE: Record = { file: MediaFileType.FILE, }; -/** Re-export source types so callers can construct them without importing media-source. */ -export type { MediaSource, RawMediaSource } from "./media-source.js"; - /** * Options for the unified {@link sendMedia} API. * * This replaces the legacy four-method surface * (`sendImage / sendVoiceMessage / sendVideoMessage / sendFileMessage`). */ -export interface SendMediaOptions { +interface SendMediaOptions { /** Delivery target. Only `c2c` and `group` support rich media. */ target: DeliveryTarget; /** Account credentials. */ diff --git a/extensions/qqbot/src/engine/messaging/streaming-c2c.ts b/extensions/qqbot/src/engine/messaging/streaming-c2c.ts index 8e49e32f664..88727be0322 100644 --- a/extensions/qqbot/src/engine/messaging/streaming-c2c.ts +++ b/extensions/qqbot/src/engine/messaging/streaming-c2c.ts @@ -210,7 +210,7 @@ class FlushController { // ============ StreamingController ============ /** StreamingController 的依赖注入 */ -export interface StreamingControllerDeps { +interface StreamingControllerDeps { /** QQ Bot 账户配置 */ account: GatewayAccount; /** 目标用户 openid(流式 API 仅支持 C2C) */ @@ -1105,7 +1105,7 @@ export class StreamingController { // ============ 流式媒体发送 ============ /** 流式媒体发送上下文(由 gateway 注入到 StreamingController) */ -export interface StreamingMediaContext { +interface StreamingMediaContext { /** 账户信息 */ account: GatewayAccount; /** 事件信息 */ diff --git a/extensions/qqbot/src/engine/messaging/streaming-media-send.ts b/extensions/qqbot/src/engine/messaging/streaming-media-send.ts index 45f81e059e8..fda3ef7b788 100644 --- a/extensions/qqbot/src/engine/messaging/streaming-media-send.ts +++ b/extensions/qqbot/src/engine/messaging/streaming-media-send.ts @@ -161,7 +161,7 @@ function isInsideCodeBlock(text: string, position: number): boolean { // ============ 媒体标签解析 ============ /** findFirstClosedMediaTag 的返回值 */ -export interface FirstClosedMediaTag { +interface FirstClosedMediaTag { /** 标签前的纯文本 */ textBefore: string; /** 标签类型(小写,如 "qqvoice") */ diff --git a/extensions/qqbot/src/engine/messaging/target-parser.ts b/extensions/qqbot/src/engine/messaging/target-parser.ts index 1831ce576a4..ed888f8e512 100644 --- a/extensions/qqbot/src/engine/messaging/target-parser.ts +++ b/extensions/qqbot/src/engine/messaging/target-parser.ts @@ -7,10 +7,10 @@ */ /** Supported target types. */ -export type TargetType = "c2c" | "group" | "channel"; +type TargetType = "c2c" | "group" | "channel"; /** Parsed delivery target. */ -export interface ParsedTarget { +interface ParsedTarget { type: TargetType; id: string; } diff --git a/extensions/qqbot/src/engine/tools/channel-api.ts b/extensions/qqbot/src/engine/tools/channel-api.ts index 3e7c6cad0a7..88ac4d06b46 100644 --- a/extensions/qqbot/src/engine/tools/channel-api.ts +++ b/extensions/qqbot/src/engine/tools/channel-api.ts @@ -108,7 +108,7 @@ function json(data: unknown) { * Options provided by the caller when executing a channel API request. * 执行频道 API 请求时由调用方提供的选项。 */ -export interface ChannelApiExecuteOptions { +interface ChannelApiExecuteOptions { accessToken: string; } diff --git a/extensions/qqbot/src/engine/tools/remind-logic.ts b/extensions/qqbot/src/engine/tools/remind-logic.ts index 45fde9b2c13..d1f5a6a2ad3 100644 --- a/extensions/qqbot/src/engine/tools/remind-logic.ts +++ b/extensions/qqbot/src/engine/tools/remind-logic.ts @@ -28,7 +28,7 @@ export interface RemindParams { * `fallbackAccountId` are consulted only when the corresponding AI-supplied * parameter is missing. */ -export interface RemindExecuteContext { +interface RemindExecuteContext { fallbackTo?: string; fallbackAccountId?: string; } @@ -41,9 +41,9 @@ export type RemindCronAction = job: ReturnType["job"] | ReturnType["job"]; }; -export type RemindCronScheduler = (params: RemindCronAction) => Promise; +type RemindCronScheduler = (params: RemindCronAction) => Promise; -export type RemindCronPlan = +type RemindCronPlan = | { ok: true; action: RemindParams["action"]; @@ -181,7 +181,7 @@ export function buildReminderPrompt(content: string): string { } /** Build cron job params for a one-shot delayed reminder. */ -export function buildOnceJob(params: RemindParams, delayMs: number, to: string, accountId: string) { +function buildOnceJob(params: RemindParams, delayMs: number, to: string, accountId: string) { const atMs = Date.now() + delayMs; const content = params.content!; const name = params.name || generateJobName(content); @@ -208,7 +208,7 @@ export function buildOnceJob(params: RemindParams, delayMs: number, to: string, } /** Build cron job params for a recurring cron reminder. */ -export function buildCronJob(params: RemindParams, to: string, accountId: string) { +function buildCronJob(params: RemindParams, to: string, accountId: string) { const content = params.content!; const name = params.name || generateJobName(content); const tz = params.timezone || "Asia/Shanghai"; diff --git a/extensions/qqbot/src/engine/utils/attachment-tags.ts b/extensions/qqbot/src/engine/utils/attachment-tags.ts index 48db94ad37f..c52fcdc60d2 100644 --- a/extensions/qqbot/src/engine/utils/attachment-tags.ts +++ b/extensions/qqbot/src/engine/utils/attachment-tags.ts @@ -44,7 +44,7 @@ export type AttachmentSummary = RefAttachmentSummary; * transcripts when `transcriptSource` is present. Tags are separated * by spaces so the block fits on one line. */ -export type RenderMode = "inline" | "ref"; +type RenderMode = "inline" | "ref"; /** Human-readable labels for transcript provenance (prompt contract). */ export const TRANSCRIPT_SOURCE_LABELS: Record< @@ -58,7 +58,7 @@ export const TRANSCRIPT_SOURCE_LABELS: Record< }; /** Options controlling how the tag list is rendered. */ -export interface RenderOptions { +interface RenderOptions { mode: RenderMode; /** Separator between tags. Defaults per mode: inline=`\n`, ref=` `. */ separator?: string; diff --git a/extensions/qqbot/src/engine/utils/diagnostics.ts b/extensions/qqbot/src/engine/utils/diagnostics.ts index f3503ffdaca..7ccbcc3c529 100644 --- a/extensions/qqbot/src/engine/utils/diagnostics.ts +++ b/extensions/qqbot/src/engine/utils/diagnostics.ts @@ -18,7 +18,7 @@ import { checkSilkWasmAvailable, } from "./platform.js"; -export interface DiagnosticReport { +interface DiagnosticReport { platform: string; arch: string; nodeVersion: string; diff --git a/extensions/qqbot/src/engine/utils/file-utils.ts b/extensions/qqbot/src/engine/utils/file-utils.ts index 396d3408e53..2ce1dacea3c 100644 --- a/extensions/qqbot/src/engine/utils/file-utils.ts +++ b/extensions/qqbot/src/engine/utils/file-utils.ts @@ -11,7 +11,7 @@ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "./stri export const MAX_UPLOAD_SIZE = 20 * 1024 * 1024; /** Absolute upper bound enforced on the chunked upload path (matches server policy). */ -export const CHUNKED_UPLOAD_MAX_SIZE = 100 * 1024 * 1024; +const CHUNKED_UPLOAD_MAX_SIZE = 100 * 1024 * 1024; /** Threshold used to treat an upload as a large file (dispatch to chunked path). */ export const LARGE_FILE_THRESHOLD = 5 * 1024 * 1024; @@ -24,7 +24,7 @@ export const LARGE_FILE_THRESHOLD = 5 * 1024 * 1024; * `MEDIA_FILE_TYPE_INFO[MediaFileType.IMAGE].maxSize`, and adding a new * type forces both fields to be supplied in a single place. */ -export const MEDIA_FILE_TYPE_INFO: Record = { +const MEDIA_FILE_TYPE_INFO: Record = { [MediaFileType.IMAGE]: { maxSize: 30 * 1024 * 1024, name: "图片" }, [MediaFileType.VIDEO]: { maxSize: 100 * 1024 * 1024, name: "视频" }, [MediaFileType.VOICE]: { maxSize: 20 * 1024 * 1024, name: "语音" }, @@ -63,7 +63,7 @@ export const QQBOT_MEDIA_SSRF_POLICY: SsrfPolicyConfig = { }; /** Result of local file-size validation. */ -export interface FileSizeCheckResult { +interface FileSizeCheckResult { ok: boolean; size: number; error?: string; diff --git a/extensions/qqbot/src/engine/utils/image-size.ts b/extensions/qqbot/src/engine/utils/image-size.ts index aabcb78be35..f3c6a56a8bd 100644 --- a/extensions/qqbot/src/engine/utils/image-size.ts +++ b/extensions/qqbot/src/engine/utils/image-size.ts @@ -10,7 +10,7 @@ import type { SsrfPolicyConfig } from "../adapter/types.js"; import { formatErrorMessage } from "./format.js"; import { debugLog } from "./log.js"; -export interface ImageSize { +interface ImageSize { width: number; height: number; } diff --git a/extensions/qqbot/src/engine/utils/payload.ts b/extensions/qqbot/src/engine/utils/payload.ts index a5bf529d2ca..b32adca0bbb 100644 --- a/extensions/qqbot/src/engine/utils/payload.ts +++ b/extensions/qqbot/src/engine/utils/payload.ts @@ -27,10 +27,10 @@ export interface MediaPayload { caption?: string; } -export type QQBotPayload = CronReminderPayload | MediaPayload; +type QQBotPayload = CronReminderPayload | MediaPayload; /** Result of parsing model output into a structured payload. */ -export interface ParseResult { +interface ParseResult { isPayload: boolean; payload?: QQBotPayload; text?: string; diff --git a/extensions/qqbot/src/engine/utils/platform.ts b/extensions/qqbot/src/engine/utils/platform.ts index 7fcfab77be8..826680b0f62 100644 --- a/extensions/qqbot/src/engine/utils/platform.ts +++ b/extensions/qqbot/src/engine/utils/platform.ts @@ -90,7 +90,7 @@ function getOpenClawMediaDir(): string { // ---- Basic platform information ---- -export type PlatformType = "darwin" | "linux" | "win32" | "other"; +type PlatformType = "darwin" | "linux" | "win32" | "other"; export function getPlatform(): PlatformType { const p = process.platform; diff --git a/extensions/qqbot/src/engine/utils/request-context.ts b/extensions/qqbot/src/engine/utils/request-context.ts index ba682546430..674222f784f 100644 --- a/extensions/qqbot/src/engine/utils/request-context.ts +++ b/extensions/qqbot/src/engine/utils/request-context.ts @@ -18,7 +18,7 @@ import { AsyncLocalStorage } from "node:async_hooks"; /** Context values available during one inbound message handling cycle. */ -export interface RequestContext { +interface RequestContext { /** The account ID handling this request. */ accountId: string; /** diff --git a/extensions/qqbot/src/engine/utils/string-normalize.ts b/extensions/qqbot/src/engine/utils/string-normalize.ts index 40a7d08630a..9561b48eb98 100644 --- a/extensions/qqbot/src/engine/utils/string-normalize.ts +++ b/extensions/qqbot/src/engine/utils/string-normalize.ts @@ -12,7 +12,7 @@ // ---- String coercion ---- /** Return the trimmed string or `null` when the value is not a non-empty string. */ -export function normalizeNullableString(value: unknown): string | null { +function normalizeNullableString(value: unknown): string | null { if (typeof value !== "string") { return null; } diff --git a/extensions/qqbot/src/engine/utils/stt.ts b/extensions/qqbot/src/engine/utils/stt.ts index 30332995abd..41c00fec148 100644 --- a/extensions/qqbot/src/engine/utils/stt.ts +++ b/extensions/qqbot/src/engine/utils/stt.ts @@ -14,7 +14,7 @@ import { sanitizeFileName, } from "./string-normalize.js"; -export interface STTConfig { +interface STTConfig { baseUrl: string; apiKey: string; model: string;