mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:10:45 +00:00
refactor: trim qqbot helper exports
This commit is contained in:
@@ -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) ============
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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().
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -31,7 +31,7 @@ import type { GatewayAccount, EngineLogger, GatewayPluginRuntime, WSPayload } fr
|
||||
|
||||
// ============ Connection context ============
|
||||
|
||||
export interface GatewayConnectionContext {
|
||||
interface GatewayConnectionContext {
|
||||
account: GatewayAccount;
|
||||
abortSignal: AbortSignal;
|
||||
cfg: unknown;
|
||||
|
||||
@@ -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<string, unknown>) => 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>) => void;
|
||||
getSnapshot: (senderPeerId: string) => QueueSnapshot;
|
||||
|
||||
@@ -49,7 +49,7 @@ const TOOL_MEDIA_SEND_TIMEOUT = 45_000;
|
||||
|
||||
// ============ Dependencies ============
|
||||
|
||||
export interface OutboundDispatchDeps {
|
||||
interface OutboundDispatchDeps {
|
||||
runtime: GatewayPluginRuntime;
|
||||
cfg: unknown;
|
||||
account: GatewayAccount;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<unknown>;
|
||||
|
||||
/** 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 {
|
||||
|
||||
@@ -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<string, unknown>,
|
||||
agentId: string | undefined,
|
||||
): string {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<void>;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<MediaSendResult>;
|
||||
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 = <T>(sendFn: (token: string) => Promise<T>) => Promise<T>;
|
||||
type SendWithRetryFn = <T>(sendFn: (token: string) => Promise<T>) => Promise<T>;
|
||||
|
||||
/** 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;
|
||||
|
||||
@@ -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<T>(
|
||||
// ---- Text routing ----
|
||||
|
||||
/** Route a text message to the correct QQ target type. */
|
||||
export async function sendTextToTarget(
|
||||
ctx: ReplyContext,
|
||||
text: string,
|
||||
refIdx?: string,
|
||||
): Promise<void> {
|
||||
async function sendTextToTarget(ctx: ReplyContext, text: string, refIdx?: string): Promise<void> {
|
||||
const { target, account } = ctx;
|
||||
const deliveryTarget = buildDeliveryTarget(target);
|
||||
const creds = accountToCreds(account);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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<MediaKind, MediaFileType> = {
|
||||
@@ -538,16 +535,13 @@ const KIND_TO_FILE_TYPE: Record<MediaKind, MediaFileType> = {
|
||||
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. */
|
||||
|
||||
@@ -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;
|
||||
/** 事件信息 */
|
||||
|
||||
@@ -161,7 +161,7 @@ function isInsideCodeBlock(text: string, position: number): boolean {
|
||||
// ============ 媒体标签解析 ============
|
||||
|
||||
/** findFirstClosedMediaTag 的返回值 */
|
||||
export interface FirstClosedMediaTag {
|
||||
interface FirstClosedMediaTag {
|
||||
/** 标签前的纯文本 */
|
||||
textBefore: string;
|
||||
/** 标签类型(小写,如 "qqvoice") */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<typeof buildOnceJob>["job"] | ReturnType<typeof buildCronJob>["job"];
|
||||
};
|
||||
|
||||
export type RemindCronScheduler = (params: RemindCronAction) => Promise<unknown>;
|
||||
type RemindCronScheduler = (params: RemindCronAction) => Promise<unknown>;
|
||||
|
||||
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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
checkSilkWasmAvailable,
|
||||
} from "./platform.js";
|
||||
|
||||
export interface DiagnosticReport {
|
||||
interface DiagnosticReport {
|
||||
platform: string;
|
||||
arch: string;
|
||||
nodeVersion: string;
|
||||
|
||||
@@ -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<MediaFileType, { maxSize: number; name: string }> = {
|
||||
const MEDIA_FILE_TYPE_INFO: Record<MediaFileType, { maxSize: number; name: string }> = {
|
||||
[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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
sanitizeFileName,
|
||||
} from "./string-normalize.js";
|
||||
|
||||
export interface STTConfig {
|
||||
interface STTConfig {
|
||||
baseUrl: string;
|
||||
apiKey: string;
|
||||
model: string;
|
||||
|
||||
Reference in New Issue
Block a user